#include "common.h"
EXTERN  U4B                        atamaxsectors;/*In the fsdriver*/
EXTERN  PSUPER                     fssupercluster;/*In the fsserver*/
EXTERN  PCLUSTER                   fsdynamic;/*In the fsserver*/
EXTERN  PFSMEMORYCONTROL           fscontrol;/*In the fsserver*/



PUBLIC S4B VerifyFSValidity()
{
    PSUPER   psuper=(PSUPER)fsbuffer;
    MESSAGE  message;
    message.destination=FSDRIVER;
    message.type=FSDRIVER_READ;
    message.value0=0; /*start*/
    message.value1=8; /*number*/
    message.value2=(U4B)psuper;/*buffer*/
    SafeSend(&message);
    SIGNAL signal;
    signal.dt=0;
    signal.signal=FSDRIVER_READ;
    signal.sourcepid=FSDRIVER;
    WaitSignal(&signal);
    if(psuper->s_magic==PETAL_MAGIC) 
      return 0;
    else
      return 1;
} 

PUBLIC S4B SetupFileSystem()
{
    PSUPER psuper=(PSUPER)fsbuffer;
    MemorySet((PVOID)(((PU1B)psuper)+512),sizeof(SECTOR)*7,0x0); /*I don't change the boot sector.*/
    psuper->s_magic=PETAL_MAGIC;
    psuper->s_clustersize=sizeof(SECTOR)*8;/*byte number per cluster*/
    psuper->s_directoryitemsize=sizeof(DIRECTORYITEM);
    psuper->s_fileitemsize=sizeof(FILEITEM);
    (psuper->s_clustersum).low=atamaxsectors/8;
    (psuper->s_clustersum).high=0;
    (psuper->s_remainnumber).low=(atamaxsectors/8)-1;
    (psuper->s_remainnumber).high=0;
    (psuper->s_virgincluster).low=1;
    (psuper->s_virgincluster).high=0;
    (psuper->s_freecluster).low=PETAL_INVALID;
    (psuper->s_freecluster).high=PETAL_INVALID;
    (psuper->s_root).e_type=PETAL_DIRECTORY;
    (psuper->s_root).e_startcluster.low=PETAL_INVALID;
    (psuper->s_root).e_startcluster.high=PETAL_INVALID;
    (psuper->s_root).e_size.low=0;
    (psuper->s_root).e_size.high=0;
    (psuper->s_root).e_nameblock.low=PETAL_INVALID;
    (psuper->s_root).e_nameblock.high=PETAL_INVALID;	
    (psuper->s_root).e_id.high=0;
	(psuper->s_root).e_id.low=0;
	 psuper->s_distributeid.low=0;
	 psuper->s_distributeid.high=0;
    MemoryCopy((psuper->s_root).e_name,".\0",2);
    
    MESSAGE message;
    message.destination=FSDRIVER;
    message.type=FSDRIVER_WRITE;
    message.value0=0; /*start*/
    message.value1=8; /*number*/
    message.value2=(U4B)psuper;/*buffer*/
    SafeSend(&message);
    SIGNAL signal;
    signal.dt=0;
    signal.signal=FSDRIVER_WRITE;
    signal.sourcepid=FSDRIVER;
    WaitSignal(&signal);
    
  return 0;
}

PUBLIC S4B SetupFSBufferControl()
{
   PFSMEMORYCONTROL pfsctrl=(PFSMEMORYCONTROL)fsbuffer;
   U4B ctrlnumber=FILESYSTEM_BUFFERSIZE/(sizeof(CLUSTER));
   U4B ctrlclusternumber=(ctrlnumber*sizeof(FSMEMORYCONTROL)+sizeof(CLUSTER)-1)/sizeof(CLUSTER);
   MemorySet((PVOID)(pfsctrl),sizeof(CLUSTER)*ctrlclusternumber,0x0); 
   U4B i;
   for(i=0;i<ctrlclusternumber;i++)
   {  
        pfsctrl[i].attribute=0x3;
        pfsctrl[i].fromcluster.low=ctrlclusternumber;
        pfsctrl[i].fromcluster.high=0x0;
        pfsctrl[i].usrnumber=ctrlnumber;  /*Used in function FindFreeClusterControl*/
   } 
   fssupercluster=(PSUPER)(((PU1B)pfsctrl)+sizeof(CLUSTER)*ctrlclusternumber);
   fsdynamic=(PCLUSTER)(((PU1B)fssupercluster)+sizeof(CLUSTER));
   fscontrol=pfsctrl;
   return 0;
}

PUBLIC S4B LoadSuperCluster()
{
    PSUPER psuper=(PSUPER)fssupercluster;
    MESSAGE message;
    message.destination=FSDRIVER;
    message.type=FSDRIVER_READ;
    message.value0=0; /*start*/
    message.value1=8; /*number*/
    message.value2=(U4B)psuper;/*buffer*/
    SafeSend(&message);
    SIGNAL signal;
    signal.dt=0;
    signal.signal=FSDRIVER_READ;
    signal.sourcepid=FSDRIVER;
    WaitSignal(&signal);
    U4B  supercontrol=(((((PU1B)fssupercluster)-((PU1B)fscontrol)))/sizeof(CLUSTER));
    fscontrol[supercontrol].attribute=0x3;
	fscontrol[supercontrol].usrnumber=1;
    fscontrol[supercontrol].fromcluster.low=0;
    fscontrol[supercontrol].fromcluster.high=0;
    return 0;
}

PUBLIC S4B SaveSuperCluster()
{
    PSUPER psuper=(PSUPER)fssupercluster;
    MESSAGE message;
    message.destination=FSDRIVER;
    message.type=FSDRIVER_WRITE;
    message.value0=0; /*start*/
    message.value1=8; /*number*/
    message.value2=(U4B)psuper;/*buffer*/
    SafeSend(&message);
    SIGNAL signal;
    signal.dt=0;
    signal.signal=FSDRIVER_WRITE;
    signal.sourcepid=FSDRIVER;
    WaitSignal(&signal);
    return 0;
}

PUBLIC S4B ApplyForACluster(PULLONG pvalue )
{
    *pvalue=fssupercluster->s_virgincluster;
    AddULLONGU4B(&(fssupercluster->s_virgincluster),(fssupercluster->s_virgincluster),1);
	SubductULLONGU4B(&(fssupercluster->s_remainnumber),(fssupercluster->s_remainnumber),1);
    SaveSuperCluster();
    return 0; 
}

PUBLIC S4B FindFreeClusterControl(PU4B pcontrol)
{
   U4B i;
   for(i=0;i<fscontrol[0].usrnumber;i++)
   {
      if((fscontrol[i].attribute & 0x1)==0) /*not used*/
	  	break;
   }
   if(i==fscontrol[0].usrnumber)
   	return 1;
   fscontrol[i].attribute=0x1;
   fscontrol[i].usrnumber=1;
   *pcontrol=i;
   return 0;
}

PUBLIC S4B ReleaseControl(U4B control)
{
   if(fscontrol[control].attribute & 0x2)
   	return 1;
   
   if(fscontrol[control].usrnumber>0)
   	fscontrol[control].usrnumber--;
   
   if(fscontrol[control].usrnumber>0 && ((fscontrol[control].attribute & 0x1)!=0))
   	return 0;
   
   fscontrol[control].attribute=0x0;
   fscontrol[control].fileid.high=0;     fscontrol[control].fileid.low=0;
   fscontrol[control].fromcluster.high=0;fscontrol[control].fromcluster.low=0;
   fscontrol[control].offset.high=0;     fscontrol[control].offset.low=0;
   fscontrol[control].usrnumber=0;
   return 0;
}

PUBLIC S4B BindControlCluster(U4B control,ULLONG cluster)
{
	 fscontrol[control].fromcluster=cluster;
	 return 0;
}

PUBLIC S4B LoadCluster(ULLONG position,U4B control)
{
	if(control<((((((PU1B)fssupercluster)-((PU1B)fscontrol)))/sizeof(CLUSTER)))) return 1;
    fscontrol[control].fromcluster=position;

    MESSAGE message;
    message.destination=FSDRIVER;
    message.type=FSDRIVER_READ;
    message.value0=position.low*8; /*start*/
    message.value1=8; /*number*/
    message.value2=(U4B)FSControlToAddress(control);/*buffer*/
    SafeSend(&message);
    SIGNAL signal;
    signal.dt=0;
    signal.signal=FSDRIVER_READ;
    signal.sourcepid=FSDRIVER;
    WaitSignal(&signal);
    return 0;
}

PUBLIC S4B SaveCluster(U4B control,ULLONG destination)
{
    if(control<((((((PU1B)fssupercluster)-((PU1B)fscontrol)))/sizeof(CLUSTER)))) return 1;
    MESSAGE message;
    message.destination=FSDRIVER;
    message.type=FSDRIVER_WRITE;
    message.value0=destination.low*8; /*start*/
    message.value1=8; /*number*/
    message.value2=(U4B)FSControlToAddress(control);/*buffer*/
    SafeSend(&message);
    SIGNAL signal;
    signal.dt=0;
    signal.signal=FSDRIVER_WRITE;
    signal.sourcepid=FSDRIVER;
    WaitSignal(&signal);
   return 0;
}

PUBLIC S4B SaveDefaultControl(U4B control)
{
     MESSAGE message;
     message.destination=FSDRIVER;
     message.type=FSDRIVER_WRITE;
     message.value0=fscontrol[control].fromcluster.low*8;
     message.value1=8;
     message.value2=(U4B)FSControlToAddress(control);
     SafeSend(&message);
     SIGNAL signal;
     signal.dt=0;
     signal.signal=FSDRIVER_WRITE;
     signal.sourcepid=FSDRIVER;
     WaitSignal(&signal);
     return 0;
}

PUBLIC S4B FSPathType(PCHAR name,PU4B type)
{
   U4B number;
   GetCharacterNumber(name,&number);
   if(number==0) return 1;
   name+=(number-1);
   if(*name=='/') 
   	  *type=PETAL_DIRECTORY;  /*directory*/
   else
   { 
     
   	  *type=PETAL_FILE;/*file*/
   }
   return 0;
}

PUBLIC S4B FSPathLevel(PCHAR name,PU4B levelnumber)
{
    CharacterRepeatNumber(name,'/',levelnumber);
    return  0;
} 

PUBLIC S4B LocateLevelName(PCHAR name,U4B level,PPCHAR next)
{
  if(level==0)
  	return 1;
  if(LocateCharacter(name,level,'/',next)!=0)/*fail*/ /*serial :1,2,3,4...*/
  {
     return 1;
  }
  (*next)++;
  return 0;
}

PUBLIC S4B GetAnID(PULLONG pid)
{
    AddULLONGU4B(&(fssupercluster->s_distributeid),fssupercluster->s_distributeid,1);
    *pid=fssupercluster->s_distributeid;
	SaveSuperCluster();
    return 0;
}

PUBLIC S4B InitDirectoryBuffer(U4B control,ULLONG upper,U4B upperindex,ULLONG previous,ULLONG next)
{
   PPETALDIRECTORY pdir=(PPETALDIRECTORY)FSControlToAddress(control);
   MemorySet((PVOID)pdir,sizeof(PETALDIRECTORY),0x0);
   pdir->linker.l_next=next;
   pdir->linker.l_previous=previous;
   pdir->linker.l_upper=upper;
   pdir->linker.l_upperindex=upperindex;
   return 0;
}



/*--------------------------------------------------------------------------------------------------*/
PUBLIC S4B CreateFileAndFolder(PCHAR name,/*return*/PULLONG pwhere,/*return*/PU4B pindex)
{
   U4B control;
   if(FindFreeClusterControl(&control)!=0)return 1;
   
   U4B type;
   if(FSPathType(name,&type)!=0)return 1;
   
   S4B level;
   if(FSPathLevel(name,(PU4B)&level)!=0)return 1;
   
   if(level==0)return 1;

   if(level==1 && type==PETAL_DIRECTORY) return 1;
   
   PPETALDIRECTORY plist;
   pwhere->low= PETAL_INVALID;
   pwhere->high=PETAL_INVALID;
   
 /*-----------------------Load the root directory---------------------------*/
   ULLONG pointer=fssupercluster->s_root.e_startcluster;   
   ULLONG id;
   if(pointer.low==PETAL_INVALID && pointer.high==PETAL_INVALID)
   {
     ApplyForACluster(&pointer);
	 
     fssupercluster->s_root.e_startcluster=pointer;
     SaveSuperCluster();
	 
     U4B j;FindFreeClusterControl(&j);
	 ULLONG root;
	 root.high=0;
	 root.low=0;
	 ULLONG invalid;
	 invalid.high=PETAL_INVALID;
	 invalid.low=PETAL_INVALID;
     InitDirectoryBuffer(j,root,5,invalid,invalid);
     SaveCluster(j,pointer);
	 
     ReleaseControl(j);
   }
   
   plist=(PPETALDIRECTORY)FSControlToAddress(control);
   LoadCluster(pointer,control);
   
   if(type==PETAL_DIRECTORY)
    level-=1;


   S4B index=0,k,j,m;
   
   for(k=1;k<=level;k++)
   {
      ULLONG emptyin;
      emptyin.low=PETAL_INVALID;
      emptyin.high=PETAL_INVALID;
      U4B filetype=PETAL_DIRECTORY;
      if(k==level && type==PETAL_FILE) filetype=PETAL_FILE;
	  
      PCHAR thislevelname;
	  LocateLevelName(name,k,&thislevelname);




      /*Try to find the file,when come across the extended cluster ,load it*/
      for(j=0;j<=31;j++)
      {
         if(j==31 )
		 {
		 	if( !((plist->linker).l_next.high==PETAL_INVALID && (plist->linker).l_next.low==PETAL_INVALID))
		 	{
		 	   LoadCluster((plist->linker).l_next,control);
			   j=-1;
			   continue;
		 	}
			else
			{
			   break;/*Not find.*/
			}
		 }
         if(plist->entry[j].e_type==filetype && CompareString(thislevelname,'/',plist->entry[j].e_name,'\0')==0) /*find*/
         { index=j; goto CREATEFILEANDFOLDER_FIND;}
		 
         if(plist->entry[j].e_type==PETAL_INVALID) emptyin=fscontrol[control].fromcluster;
      }   


	  
      /*-------------Not find in this level---------*/
   /*-----------In this level to create one.------------*/
     if(!(emptyin.low==PETAL_INVALID && emptyin.high==PETAL_INVALID))
     {
       if(!(emptyin.high==fscontrol[control].fromcluster.high && emptyin.low==fscontrol[control].fromcluster.low))
       { LoadCluster(emptyin,control);}
	   
       for(m=0;m<31;m++)
       {
          if(plist->entry[m].e_type==PETAL_INVALID)
          {
             
			 GetAnID(&id);
             plist->entry[m].e_type=filetype;
             StringCopyWithEnd(plist->entry[m].e_name,32,thislevelname,'/');
             plist->entry[m].e_startcluster.low =PETAL_INVALID;
             plist->entry[m].e_startcluster.high=PETAL_INVALID;
             plist->entry[m].e_size.low=0;/*file:0bytes,directory:0items*/
             plist->entry[m].e_size.high=0;
			 plist->entry[m].e_id=id;
             SaveDefaultControl(control);
             index=m;
			 
			 U4B u=0;FindFreeClusterControl(&u);
			 PPETALDIRECTORY p=(PPETALDIRECTORY)FSControlToAddress(u);
			 LoadCluster(plist->linker.l_upper,u);
			 AddULLONGU4B(&(p->entry[plist->linker.l_upperindex].e_size),(p->entry[plist->linker.l_upperindex].e_size),1);
			 SaveDefaultControl(u);
			 ReleaseControl(u);

			 goto  CREATEFILEANDFOLDER_FIND;
           }
       }
      }
     /*----------No empty place to use,it means the last cluster this level is in the memory------------*/
      
                   ULLONG p;
                   ApplyForACluster(&p);
                   U4B n=0;
				   FindFreeClusterControl(&n);
				   ULLONG invalid;
				   invalid.low=PETAL_INVALID;invalid.high=PETAL_INVALID;
                   InitDirectoryBuffer(n,plist->linker.l_upper,plist->linker.l_upperindex,fscontrol[control].fromcluster,invalid);
				   plist->linker.l_next=p;
                   SaveCluster(n,p);
                   ReleaseControl(n);
                   SaveDefaultControl(control);
				   
                   LoadCluster(p,control);
				   GetAnID(&id);
                   plist->entry[0].e_type=filetype;
                   StringCopyWithEnd(plist->entry[0].e_name,32,thislevelname,'/');
                   plist->entry[0].e_startcluster.low =PETAL_INVALID;
                   plist->entry[0].e_startcluster.high=PETAL_INVALID;
                   plist->entry[0].e_size.low =0;
                   plist->entry[0].e_size.high=0;
				   plist->entry[0].e_id=id;

                   SaveDefaultControl(control);
                   
				   U4B u=0;FindFreeClusterControl(&u);
				   PPETALDIRECTORY po=(PPETALDIRECTORY)FSControlToAddress(u);
				   LoadCluster(plist->linker.l_upper,u);
				   AddULLONGU4B(&(po->entry[plist->linker.l_upperindex].e_size),(po->entry[plist->linker.l_upperindex].e_size),1);
				   SaveDefaultControl(u);
				   ReleaseControl(u);
				   
                   index=0;
         
      
         

CREATEFILEANDFOLDER_FIND:       /*find the entry item*/
     if(k<level)/*a direcotry*/
     {
        if(plist->entry[index].e_startcluster.low==PETAL_INVALID && plist->entry[index].e_startcluster.high==PETAL_INVALID)
        { 
            ULLONG p;
            ApplyForACluster(&p);
            plist->entry[index].e_startcluster=p;
			
            U4B m;FindFreeClusterControl(&m);
            ULLONG prev,next;
	        prev.high=PETAL_INVALID;prev.low=PETAL_INVALID;next.high=PETAL_INVALID;next.low=PETAL_INVALID;
            InitDirectoryBuffer(m,fscontrol[control].fromcluster,index,prev,next);
            SaveCluster(m,p);
            ReleaseControl(m);
			
            SaveDefaultControl(control);
		}


		
        LoadCluster(plist->entry[index].e_startcluster,control);        
     }

  }
  *pwhere=fscontrol[control].fromcluster;
  *pindex=index;
  ReleaseControl(control);
  
  return 0;
}
/*--------------------------------------------------------------------------------------------------*/




PUBLIC S4B InitFileBuffer(U4B control,ULLONG upper,U2B upperindex,ULLONG level)
{
   PPETALFILE pfile=(PPETALFILE)FSControlToAddress(control);
   MemorySet((PVOID)(pfile),sizeof(PETALFILE),0);
   pfile->head.h_upper=upper;
   pfile->head.h_upperindex=upperindex;
   pfile->head.h_level=level;
  
   return 0;
}

PUBLIC S4B InsertFile(PCHAR filename,ULLONG where,U4B howmany,PU1B pcontent)
{


  ULLONG      entrycluster;
  U4B         index;

  if(CreateFileAndFolder(filename,&entrycluster,&index)!=0)
  	return 1;


  /*------------------------These to be released--------------------------------*/
  U4B entrycontrol=0;FindFreeClusterControl(&entrycontrol);
  U4B pfilecontrol=0;FindFreeClusterControl(&pfilecontrol);
  /*----------------------------------------------------------------------------*/




/*---------------------------------Something about the Directory----------------------------------------------------------------------------- */
    PPETALDIRECTORY plist=(PPETALDIRECTORY)FSControlToAddress(entrycontrol);
    LoadCluster(entrycluster,entrycontrol);/*bind the control and the specific cluster in the hd.*/
/*----------------------A file entryitem without nothing----------------------------------------*/
  if(plist->entry[index].e_startcluster.low==PETAL_INVALID && plist->entry[index].e_startcluster.high==PETAL_INVALID)
  {
     ULLONG newcluster;
     ApplyForACluster(&newcluster);
     U4B n=0;FindFreeClusterControl(&n);
	 ULLONG level;level.low=0;level.high=0;
	 InitFileBuffer(n,entrycluster,index,level);
     SaveCluster(n,newcluster);
     ReleaseControl(n);
     plist->entry[index].e_startcluster=newcluster;
     plist->entry[index].e_size.low=0;/*byte number*/
     plist->entry[index].e_size.high=0;/*byte number*/
  }
/*---------------------To protect the file----------------------------------*/
  if( CompareULLONG(where,plist->entry[index].e_size)==1) /*a file must less than 2^64Bytes*/
  {
     where=plist->entry[index].e_size; /*the entry cluster contain the size of the file*/
  }
/*---------------------To change the size .---------------------------------*/
    ULLONG sizetemp;sizetemp.high=0;sizetemp.low=howmany;
    AddULLONG(&(plist->entry[index].e_size),plist->entry[index].e_size,sizetemp);
    SaveDefaultControl(entrycontrol);
/*---------------------The File Directory Item Is END.-----------------------------------------------------------------------------------------*/





/*-------------------------Something about the File content list ------------------------------------------------------------------------------*/
    PPETALFILE pfilelist=(PPETALFILE)FSControlToAddress(pfilecontrol);
    LoadCluster(plist->entry[index].e_startcluster,pfilecontrol);
	
    ULLONG fileposition;
    fileposition.low=0;
    fileposition.high=0;
    U4B filelistindex=0;
    ULLONG offset;      /*In the find item the insert point offset*/
    offset.low=0;
    offset.high=0;
/*-------------------------------------------------------------------------------------------*/
  while(1)
  {

    /*--------------------------To find the insert point--------------------------------------------*/
            AddULLONG(&fileposition,fileposition,pfilelist->section[0].f_size);
            filelistindex=0;
            for(;CompareULLONG(where,fileposition)==1/*fileposition<where*/ ;)
            {
              	filelistindex++;
                AddULLONG(&fileposition,fileposition,pfilelist->section[filelistindex].f_size);
            }

            Assert(filelistindex<126);/*We know that "where" must less or equal the size of the file.*/

            if(pfilelist->section[filelistindex].f_type==PETAL_EXTENDED) 
            {
               SubductULLONG(&fileposition,fileposition,pfilelist->section[filelistindex].f_size);
               LoadCluster(pfilelist->section[filelistindex].f_startcluster,pfilecontrol);
			   continue;
            }
            else
            {
               SubductULLONG(&offset,fileposition,pfilelist->section[filelistindex].f_size);      
               SubductULLONG(&offset,where,offset);  /*the offset is for the begin of a  item*/
               break;
            }
  }
/*----------------------------------------First Period End-----------------------------------------------------*/
/*
offset           :it is a  variable contain the offset relative to the begining of one ITEM.
filelistindex    :in the pfilelist ,it is the index,where the content should be inserted.
plist            :it is the directory .
index      :in the plist ,it's the index of the directory item.
where              :the insert offset relative to the begining of the file.
entrycontrol      :it's a control block index.it contains the directory.
pfilecontrol        :it's a control block index.it contains the file content list.
pfilelist            :it conteins the file content list.
*/
/*-------------------------------------------------------------------------------------------------------------*/










  S4B         insertindex;   /*In the file content list ,it point to the one be inserted.*/
  ULLONG      insertcluster; /*The file content list cluster*/
  U4B         insertoffset;  /*The offset relative to the insert  cluster's beginning.*/



/*
---------------------------------------------------------------
Find the insert point ,the type can be :
    1:PETAL_CONTENT
    2:PETAL_CONTINUOUS
---------------------------------------------------------------
*/

  if(pfilelist->section[filelistindex].f_type==PETAL_CONTINUOUS)  /*If it's a continuous cluster....*/
  {
     ULLONG newcluster;
     U4B    newcontrol=0;FindFreeClusterControl(&newcontrol);
     ULLONG contcluster=pfilelist->section[filelistindex].f_startcluster;
     ULLONG contsize   =pfilelist->section[filelistindex].f_size;

     ApplyForACluster(&newcluster);
     pfilelist->section[filelistindex].f_type=PETAL_EXTENDED;   /*---------------CHANGED!!!!!!!!----------------*/
     pfilelist->section[filelistindex].f_startcluster=newcluster;
     AddULLONGU4B(&(pfilelist->section[filelistindex].f_size),contsize,howmany);/*-------------------Change the size.------------------*/
     SaveDefaultControl(pfilecontrol);/*--------------------------------SAVE IT--------------------------*/
	 ULLONG level;
	 AddULLONGU4B(&level,pfilelist->head.h_level,1);
     InitFileBuffer(newcontrol,fscontrol[pfilecontrol].fromcluster,filelistindex,level);
     BindControlCluster(newcontrol,newcluster);   /*--------------------Bind them-------------------*/

     PPETALFILE pnewlist=(PPETALFILE)FSControlToAddress(newcontrol);

     ULLONG j;
     j.low=sizeof(CLUSTER);
     j.high=0;
     if(CompareULLONG(j,offset)<=1)  /*the offset <= a cluster*//*the insert point is in the first cluster*/
     {
             pnewlist->section[0].f_type         =PETAL_CONTENT;
             pnewlist->section[0].f_size.high    =0;
             pnewlist->section[0].f_size.low     =sizeof(CLUSTER);
             pnewlist->section[0].f_startcluster =contcluster;

             insertindex=0;
             insertcluster=newcluster;
             insertoffset=offset.low;

             AddULLONGU4B(&contcluster,contcluster,1);

             SubductULLONGU4B(&contsize,contsize,sizeof(CLUSTER));           /*the second item need it.*/

             if(CompareULLONG(j,contsize)>=2)  /*contsize>sizeof(cluster)*/
             {
                pnewlist->section[1].f_type=PETAL_CONTINUOUS;
                pnewlist->section[1].f_size=contsize;
                pnewlist->section[1].f_startcluster=contcluster;
             }
             else
             {
                pnewlist->section[1].f_type=PETAL_CONTENT;
                pnewlist->section[1].f_size=contsize;
                pnewlist->section[1].f_startcluster=contcluster;
             }
     }
     else  /*the offset > a cluster*//*Two kinds*/
     {
           /*-------------------------------------------------------------------*/
           /*if the insert point is in the last cluster*/
            ULLONG k,m;
            m.low=sizeof(CLUSTER);
            m.high=0;
            SubductULLONG(&k,contsize,offset);

            if(CompareULLONG(k,m)>=2)  /*the insert point is in the last cluster*/
            {
               m.low=2*sizeof(CLUSTER);
               m.high=0;
               Assert(CompareULLONG(m,offset)!=0);/*if this take effects,the insert point should be not in the last cluster.*/
               if(CompareULLONG(m,offset)>=2)  /*PETAL_CONTINUOUS*/
               {
                  pnewlist->section[0].f_type=PETAL_CONTINUOUS;
               }
               else
               {
                  pnewlist->section[0].f_type=PETAL_CONTENT;
               }
               m.low=sizeof(CLUSTER);
               m.high=0;
               SubductULLONGU4B(&(pnewlist->section[0].f_size),contsize,sizeof(CLUSTER));
               pnewlist->section[0].f_startcluster=contcluster;
               pnewlist->section[1].f_type=PETAL_CONTENT;
               pnewlist->section[1].f_size=m;
               DivideULLONG(&m,&k,contsize,m);
               Assert(k.low==0);
               SubductULLONGU4B(&m,m,1);
               AddULLONG(&(pnewlist->section[1].f_startcluster),contcluster,m);
               insertindex=1;
               insertcluster=newcluster;
               SubductULLONG(&m,offset,pnewlist->section[0].f_size);
               insertoffset=m.low;
            }
            /*---------------------------------------------------------------------------------------*/
            else  /*the insert point in the middle of the continuous cluster*/
            {
                /*the first and third part can be PETAL_CONTINUOUS or PETAL_CONTENT*/
               /*The first part*/
               k=offset;
               m.low=1;
               m.high=0;
			   ULLONG remain;
               SubductULLONG(&k,k,m);
               DivideULLONGU4B(&k,&remain,k,sizeof(CLUSTER));
               Assert(k.low!=0);
               if(k.low<=1)
               {
                  pnewlist->section[0].f_type=PETAL_CONTENT;
                  pnewlist->section[0].f_size.low=sizeof(CLUSTER);
                  pnewlist->section[0].f_size.high=0;
                  pnewlist->section[0].f_startcluster=contcluster;
               }
               else
               {
                  
                  pnewlist->section[0].f_type=PETAL_CONTINUOUS;
				  //ULLONG temp;
				  MultiplyULLONGU4B(&(pnewlist->section[0].f_size),k,sizeof(CLUSTER));
                  pnewlist->section[0].f_startcluster=contcluster;
               }

               /*the third part*/
               SubductULLONG(&k,contsize,offset);
               DivideULLONGU4B(&k,&remain,k,sizeof(CLUSTER));
               Assert(k.low!=0);
               if(k.low<=1)
               {
                   pnewlist->section[2].f_type=PETAL_CONTENT;
                   pnewlist->section[2].f_size.low=sizeof(CLUSTER);
                   pnewlist->section[2].f_size.high=0;
                   DivideULLONGU4B(&k,&remain,contsize,sizeof(CLUSTER));
                   m.low=1;m.high=0;
                   AddULLONG(&k,contcluster,k);
                   SubductULLONG(&k,k,m);
                   pnewlist->section[2].f_startcluster=k;
               }
               else
               {
                   pnewlist->section[2].f_type=PETAL_CONTINUOUS;
                   MultiplyULLONGU4B(&(pnewlist->section[2].f_size),k,sizeof(CLUSTER));
				   ULLONG temp;
                   DivideULLONGU4B(&m,&temp,contsize,sizeof(CLUSTER));
                   AddULLONG(&m,contcluster,m);
                   SubductULLONG(&k,m,k);
                   pnewlist->section[2].f_startcluster=k;
               }
               /*the middle part*/
               pnewlist->section[1].f_type=PETAL_CONTENT;
               pnewlist->section[1].f_size.low=sizeof(CLUSTER);
               pnewlist->section[1].f_size.high=0;
               m.low=1;
               m.high=0;
               SubductULLONG(&(pnewlist->section[1].f_startcluster),pnewlist->section[2].f_startcluster,m);
               SubductULLONG(&m,offset,pnewlist->section[0].f_size);
               insertoffset=m.low;
               insertcluster=newcluster;
               insertindex=1;
            }

     }
     SaveCluster(newcontrol,newcluster);
     pfilelist=(PPETALFILE)FSControlToAddress(newcontrol);
     U4B  swapcontrol=newcontrol;
     newcontrol=pfilecontrol;
     pfilecontrol=swapcontrol;  /*We have bind  the newcontrol and newcluster.*/
     ReleaseControl(newcontrol);
  }
  else   /*A Common CONTENT*/
  {
       insertoffset=offset.low;
       insertcluster=entrycluster;
       insertindex=filelistindex;
  }

  /*If it's a empty file!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
  if(pfilelist->section[insertindex].f_startcluster.low==PETAL_INVALID && pfilelist->section[insertindex].f_startcluster.high==PETAL_INVALID)
  {
     pfilelist->section[insertindex].f_type=PETAL_CONTENT;
     pfilelist->section[insertindex].f_size.low=0;pfilelist->section[insertindex].f_size.high=0;
     ULLONG temp;
     ApplyForACluster(&temp);
     pfilelist->section[insertindex].f_startcluster=temp;
     SaveDefaultControl(pfilecontrol);
  }
/*The pfilecontrol has been bound to a specific cluster in the hd so far.*/
  Assert(insertoffset<=sizeof(CLUSTER));
  Assert(insertcluster.low!=PETAL_INVALID);
  Assert(pfilelist->section[insertindex].f_type==PETAL_CONTENT);
  Assert(pfilelist->section[insertindex].f_size.low>=insertoffset);
/*So far ,we just need to insert the content to a PETAL_CONTENT.*/
/*-----------------------The second period End---------------------------------------------------------------------------*/
/*
insertindex   :The index in pfilelist.It's a file content list index.It must point to a PETAL_FILEITEMPOINTER.
insertoffset   :Relative to the PETAL_FILEITEMPOINTER beginning.
insertcluster  :It shows the file content list cluster.
pfilelist         :it contain many file content list items.The insert point is in it.
pfilecontrol   :it's a control index of fscontrol,it is linked to the pfilelist.
*/








/*------------------------To insert the content.---------------------------------------------------------------------------*/

  U4B   textcontrol;FindFreeClusterControl(&textcontrol);
  LoadCluster(pfilelist->section[insertindex].f_startcluster,textcontrol);

  if(pfilelist->section[insertindex].f_size.low+howmany<=sizeof(CLUSTER))  /*The current cluster is enough .*/
  {
      PU1B movestart=(PU1B)FSControlToAddress(textcontrol);
      movestart+=insertoffset;    
      PU1B moveend=(PU1B)FSControlToAddress(textcontrol);
      moveend=moveend-1+pfilelist->section[insertindex].f_size.low;
      PU1B t=movestart;
      for(;movestart<=moveend;movestart++)
      {
         *(movestart+howmany)=*movestart;
      }
	  movestart=t;
      MemoryCopy((PCHAR)movestart,(PCHAR)pcontent,howmany);
      AddULLONGU4B(&(pfilelist->section[insertindex].f_size),(pfilelist->section[insertindex].f_size),howmany);/*Change the size.*/
      SaveDefaultControl(pfilecontrol);
      SaveDefaultControl(textcontrol);

      ReleaseControl(pfilecontrol);
      ReleaseControl(textcontrol);
      ReleaseControl(entrycontrol);
      return 0;
  }





/*---------------When the file is not enough for the content-------------*/
/*------------Apply for a cluster to place the squeezed content-------- */
  U4B   remaincontrol;FindFreeClusterControl(&remaincontrol);
  U4B   remainnumber;
  PU1B  remaincontent;

  PU1B  movestart=(PU1B)FSControlToAddress(textcontrol);
  movestart+=insertoffset;

  PU1B  movedestination=(PU1B)FSControlToAddress(remaincontrol);
  remaincontent=movedestination;
  remainnumber=(pfilelist->section[insertindex].f_size.low-insertoffset);

  MemoryCopy((PCHAR)movedestination,(PCHAR)movestart,remainnumber);

  U4B  toplacenumber=howmany;
  PCHAR toplacecontent=(PCHAR)pcontent;

  for(;movestart<(((PU1B)FSControlToAddress(textcontrol))+sizeof(CLUSTER)) && toplacenumber>0;)
  {
     *movestart=*toplacecontent;
     toplacecontent++;
     movestart++;
     toplacenumber--;
  }
  /*------The insert content is not enough to fill the cluster.The cluster is not full.-------*/
  if(movestart<(((PU1B)FSControlToAddress(textcontrol))+sizeof(CLUSTER))) 
  {
      for(;movestart<(((PU1B)FSControlToAddress(textcontrol))+sizeof(CLUSTER));movestart++)
      {
          *movestart=*remaincontent;
          remaincontent++;
          remainnumber--;
      }
      /*the remain content become the content to be placed */
      toplacecontent=(PCHAR)remaincontent;
      toplacenumber=remainnumber;
      remaincontent=PTR_INVALID;
      remainnumber=0;
  }
  pfilelist->section[insertindex].f_size.low=sizeof(CLUSTER);
  pfilelist->section[insertindex].f_size.high=0;
  SaveDefaultControl(textcontrol);
  SaveDefaultControl(pfilecontrol);
  /*the variable insertindex is the one has been used.*/
  while(1)
  {

        if(toplacenumber<=0 && remainnumber<=0)
            break;
      /*We try to collect PETAL_INVALID fileitem and move it to the next place near current one.*/
      /*-----In the fore place-----*/  
  
      S2B p=0,q=0;/*the first one is not used.*/
      while(p<insertindex)
      {
         for(;p<insertindex;p++)
         {
            if(pfilelist->section[p].f_type==PETAL_INVALID)
            {
               break;
            }
         }
         for(q=p;q<insertindex;q++)
         {
            pfilelist->section[q]=pfilelist->section[q+1];
            pfilelist->section[q+1].f_type=PETAL_INVALID;
         }
         if(p<insertindex)
         {insertindex--;}
      }
      /*The back*/
      p=125;
      while(p>(insertindex+1))
      {
         for(;p>(insertindex+1);p--)
         {
            if(pfilelist->section[p].f_type==PETAL_INVALID)
            {
               break;
            }
         }
         for(q=p;q>(insertindex+1);q--)
         {
            pfilelist->section[q]=pfilelist->section[q-1];
            pfilelist->section[q-1].f_type=PETAL_INVALID;
         }
      }
/*------------------------------------------------------------------------------------------------------------*/
         S4B  bytenumber=0;
INSERTFILE_NEXTINDEX:
        if(toplacenumber<=0 && remainnumber<=0)
            break;
      /*I have collect all the empty itempointer after the insertindex.*/
      insertindex++;   /*the next item*/
      if(insertindex>=126)      /*It means the previous one is the last one .*/
      {
          ULLONG   extendcluster;
          ApplyForACluster(&extendcluster);
          U4B extendcontrol=0;FindFreeClusterControl(&extendcontrol);
		  ULLONG level;
		  AddULLONGU4B(&level,pfilelist->head.h_level,1);
		  InitFileBuffer(extendcontrol,fscontrol[pfilecontrol].fromcluster,125,level);
          BindControlCluster(extendcontrol,extendcluster);
          PPETALFILE pextendlist=(PPETALFILE)FSControlToAddress(extendcontrol);
          pextendlist->section[0]=pfilelist->section[insertindex-1];
          SaveDefaultControl(extendcontrol);
          pfilelist->section[insertindex-1].f_type=PETAL_EXTENDED;
          pfilelist->section[insertindex-1].f_startcluster=extendcluster;
          AddULLONGU4B(&(pfilelist->section[insertindex-1].f_size),pfilelist->section[insertindex-1].f_size,(remainnumber+toplacenumber));
          SaveDefaultControl(pfilecontrol);
          U4B swapcontrol=pfilecontrol;
          pfilecontrol=extendcontrol;
          pfilelist=(PPETALFILE)FSControlToAddress(extendcontrol);
          extendcontrol=swapcontrol;  
          ReleaseControl(extendcontrol);
          insertindex=-1;
          continue;
      }
      if(pfilelist->section[insertindex].f_type==PETAL_INVALID)
      {
          ULLONG   contentcluster;
          ApplyForACluster(&contentcluster);
          U4B contentcontrol=0;FindFreeClusterControl(&contentcontrol);
          MemorySet((PVOID)FSControlToAddress(contentcontrol),sizeof(CLUSTER),0x0);
          BindControlCluster(contentcontrol,contentcluster);
          pfilelist->section[insertindex].f_type=PETAL_CONTENT;
          PU1B   filldestination=(PU1B)FSControlToAddress(contentcontrol);
         if((toplacenumber+remainnumber)>sizeof(CLUSTER))
         {
                    pfilelist->section[insertindex].f_size.high=0;pfilelist->section[insertindex].f_size.low=sizeof(CLUSTER);
         }
         else
         {
                    pfilelist->section[insertindex].f_size.high=0;pfilelist->section[insertindex].f_size.low=toplacenumber+remainnumber;
         }
		 U4B i=toplacenumber,j=remainnumber;
         for(bytenumber=0;bytenumber<i && bytenumber<sizeof(CLUSTER);bytenumber++)
         {
                 filldestination[bytenumber]=*((PU1B)toplacecontent);
                 toplacenumber--;
                 toplacecontent++;
         }
         for(;bytenumber<(i+j) && bytenumber<sizeof(CLUSTER);bytenumber++)
         {
                 filldestination[bytenumber]=*((PU1B)remaincontent);
                 remaincontent++;
                 remainnumber--;
         }
         SaveDefaultControl(pfilecontrol);
         SaveDefaultControl(contentcontrol);
         goto INSERTFILE_NEXTINDEX;
      }
      if(pfilelist->section[insertindex].f_type==PETAL_EXTENDED)
      {
          /*If enter the cluster,we will not return.*/
          AddULLONGU4B(&(pfilelist->section[insertindex].f_size),pfilelist->section[insertindex].f_size,(toplacenumber+remainnumber));
          SaveDefaultControl(pfilecontrol);
          LoadCluster(pfilelist->section[insertindex].f_startcluster,pfilecontrol);
          insertindex=-1;
          continue;
      }
	  /*Now the current one is valid.It can not provide empty space.*/
        ULLONG   extendcluster;
          ApplyForACluster(&extendcluster);
          U4B extendcontrol;FindFreeClusterControl(&extendcontrol);
		  ULLONG level;
		  AddULLONGU4B(&level,pfilelist->head.h_level,1);
		  InitFileBuffer(extendcontrol,fscontrol[pfilecontrol].fromcluster,insertindex,level);
          BindControlCluster(extendcontrol,extendcluster);
          PPETALFILE pextendlist=(PPETALFILE)FSControlToAddress(extendcontrol);
          pextendlist->section[1]=pfilelist->section[insertindex];
          SaveDefaultControl(extendcontrol);
          pfilelist->section[insertindex].f_type=PETAL_EXTENDED;
          pfilelist->section[insertindex].f_startcluster=extendcluster;
          AddULLONGU4B(&(pfilelist->section[insertindex].f_size),pfilelist->section[insertindex].f_size,(remainnumber+toplacenumber));
          SaveDefaultControl(pfilecontrol);
          U4B swapcontrol=pfilecontrol;
          pfilecontrol=extendcontrol;
          pfilelist=(PPETALFILE)FSControlToAddress(extendcontrol);
          extendcontrol=swapcontrol;  
          ReleaseControl(extendcontrol);
          insertindex=-1;

  }

 
  ReleaseControl(remaincontrol);
  ReleaseControl(textcontrol);
  ReleaseControl(entrycontrol);
  ReleaseControl(pfilecontrol);
  return 0;
}

PUBLIC S4B LocateDirectory(PCHAR name,PULLONG pwhere,/*return*/PU4B pindex)
{
	   U4B control;
	   if(FindFreeClusterControl(&control)!=0)return 1;
	   
	   U4B type;
	   if(FSPathType(name,&type)!=0)return 1;
	   
	   S4B level;
	   if(FSPathLevel(name,(PU4B)&level)!=0)return 1;
	   
	   if(level==0)return 1;

	   if(level==1 && type==PETAL_DIRECTORY) {pwhere->high=0;pwhere->low=0;*pindex=5;return 0;}
	   
	   PPETALDIRECTORY plist;
	   
	 /*-----------------------Load the root directory---------------------------*/
	   ULLONG pointer=fssupercluster->s_root.e_startcluster;   
	   if(pointer.low==PETAL_INVALID && pointer.high==PETAL_INVALID)
	   {
	      ReleaseControl(control);
		  return 1;
	   }
	   
	   plist=(PPETALDIRECTORY)FSControlToAddress(control);
	   LoadCluster(pointer,control);
	   
	   if(type==PETAL_DIRECTORY)
		level-=1;
	
	
	   S4B index=0,k,j;
	   
	   for(k=1;k<=level;k++)
	   {
		  U4B filetype=PETAL_DIRECTORY;
		  if(k==level && type==PETAL_FILE) filetype=PETAL_FILE;
		  
		  PCHAR thislevelname;
		  LocateLevelName(name,k,&thislevelname);
	
	
	
	
		  /*Try to find the file,when come across the extended cluster ,load it*/
		  for(j=0;j<=31;j++)
		  {
			 if(j==31 )
			 {
				if( !((plist->linker).l_next.high==PETAL_INVALID && (plist->linker).l_next.low==PETAL_INVALID))
				{
				   LoadCluster((plist->linker).l_next,control);
				   j=-1;
				   continue;
				}
				else
				{
					ReleaseControl(control);
				   return 1;/*Not find.*/
				}
			 }
			 if(plist->entry[j].e_type==filetype && CompareString(thislevelname,'/',plist->entry[j].e_name,'\0')==0) /*find*/
			 { index=j; break;}
			 
		  }   		 
	
	     /*find the entry item*/
		 if(k<level)/*a direcotry*/
		 {
			if(plist->entry[index].e_startcluster.low==PETAL_INVALID && plist->entry[index].e_startcluster.high==PETAL_INVALID)
			{ 
				ReleaseControl(control);
				return 1;
			}
			LoadCluster(plist->entry[index].e_startcluster,control);		
		 }



	
	  }
	  *pwhere=fscontrol[control].fromcluster;
	  *pindex=index;
	  ReleaseControl(control);
	  
	  return 0;
}

PUBLIC S4B InitEmptyBuffer(U4B control)
{
   PDUSTBIN p=(PDUSTBIN)FSControlToAddress(control);
   MemorySet((PVOID)p,sizeof(DUSTBIN),0);
   p->resource[127].t_type=PETAL_EXTENDED;
   return 0;
}

PUBLIC S4B ResumeCluster(PEMPTY pback)
{
    if(pback->t_number.high==0 && pback->t_number.low==0)
		return 0;
	if(pback->t_startcluster.high==PETAL_INVALID && pback->t_startcluster.low==PETAL_INVALID)
		return 0;
	if(pback->t_type==PETAL_INVALID)
		return 0;
    if(pback->t_type==PETAL_CONTINUOUSEMPTY && pback->t_number.low==1 &&pback->t_number.high==0)
    {
       pback->t_type=PETAL_SINGLEEMPTY;
    }

    if(pback->t_type!=PETAL_SINGLEEMPTY && pback->t_type!=PETAL_CONTINUOUSEMPTY)
	   return 0;
	if(IamaInvalidULLONGEntity(fssupercluster->s_freecluster))
    {
        if(pback->t_type==PETAL_SINGLEEMPTY)
        {
           U4B  free;FindFreeClusterControl(&free);
		   InitEmptyBuffer(free);
		   SaveCluster(free,pback->t_startcluster);
		   ReleaseControl(free);
           fssupercluster->s_freecluster=pback->t_startcluster;
		   SaveSuperCluster();
		   return 0;
        }
		if(pback->t_type==PETAL_CONTINUOUSEMPTY)
		{
		   U4B  free;FindFreeClusterControl(&free);
		   InitEmptyBuffer(free);
		   SaveCluster(free,pback->t_startcluster);
		   ReleaseControl(free);
		   fssupercluster->s_freecluster=pback->t_startcluster;
		   SaveSuperCluster();
		   SubductULLONGU4B(&(pback->t_number),(pback->t_number),1);
		   AddULLONGU4B(&(pback->t_startcluster),(pback->t_startcluster),1);
		   if(pback->t_number.low==1 && pback->t_number.high==0) pback->t_type=PETAL_SINGLEEMPTY;
		}
    }

    U4B  listcontrol=0;FindFreeClusterControl(&listcontrol);
	PDUSTBIN plist=(PDUSTBIN)FSControlToAddress(listcontrol);
	LoadCluster(fssupercluster->s_freecluster,listcontrol);
    S4B  index;
	for(index=0;index<sizeof(CLUSTER)/sizeof(EMPTY);index++)
	{
	   if(pback->t_number.high==0 && pback->t_number.low==0)
	   {
	     	return 0;
	   }
	   if(plist->resource[index].t_type==PETAL_INVALID)
	   {
	      plist->resource[index]=*pback;
		  SaveDefaultControl(listcontrol);
		  ReleaseControl(listcontrol);
		  return 0;
	   }
	   if(plist->resource[index].t_type==PETAL_EXTENDED)
	   {
	      if(IamaInvalidULLONGEntity(plist->resource[index].t_startcluster))
	      {
	         U4B free=0;FindFreeClusterControl(&free);
			 InitEmptyBuffer(free);
			 SaveCluster(free,pback->t_startcluster);
			 plist->resource[index].t_startcluster=pback->t_startcluster;
			 if(pback->t_number.low==1 && pback->t_number.high==0) 
			 {
			     ReleaseControl(free);
				 SaveDefaultControl(listcontrol);
				 ReleaseControl(listcontrol);
				 return 0;
			 }
			 if(pback->t_number.low>1 || pback->t_number.high>0)
			 {
			    ReleaseControl(free);
				SaveDefaultControl(listcontrol);
			    AddULLONGU4B(&(pback->t_startcluster),pback->t_startcluster,1);
				SubductULLONGU4B(&(pback->t_number),pback->t_number,1);
				LoadCluster(plist->resource[index].t_startcluster,listcontrol);
				index=-1;
				continue;
			 }
	      }
		  else
		  {
		     LoadCluster(plist->resource[index].t_startcluster,listcontrol);
			 index=-1;
			 continue;
		  }
	   }
	}
    return 0;
}

PUBLIC S4B DeleteFileContent(PCHAR path,ULLONG position,ULLONG length)
{
   /*Make sure that we want to delete something in a file ,not others*/
    U4B filetype=0;FSPathType(path,&filetype);
    if(filetype!=PETAL_FILE)
      return 1;
	/*------------------------------------------------------------------------------------*/
   /*Loacate the directory cluster.*/
    ULLONG cluster;
    S4B    index;
   
    if( LocateDirectory(path,&cluster,(PU4B)(&index))!=0)
		return 1;



	
    U4B        directorycontrol;
	FindFreeClusterControl(&directorycontrol);
    PPETALDIRECTORY directory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
	LoadCluster(cluster,directorycontrol);

    /*Maybe ,this sentence is not necessary .However each step is independent.^_^*/
    if(directory->entry[index].e_type!=PETAL_FILE)
    {ReleaseControl(directorycontrol);return 1;}

	/*Maybe ,the directory has no cluster.*/
    if(directory->entry[index].e_startcluster.high==PETAL_INVALID && directory->entry[index].e_startcluster.low==PETAL_INVALID)
    {
      directory->entry[index].e_size.high=0;directory->entry[index].e_size.low=0;
	  SaveDefaultControl(directorycontrol);
      ReleaseControl(directorycontrol);return 1;
    }
	
	/*position>=size,if it's an empty file ,size=0,so the position must >=size,so return.delete from the end of the file,it's so funny.*/ 
    if(CompareULLONG(position,directory->entry[index].e_size)<=1)
    {
        ReleaseControl(directorycontrol);
        return 0;
    }
	/*To protect the file.*/

    ULLONG temp;
    SubductULLONG(&temp,directory->entry[index].e_size,position);
    if(CompareULLONG(temp,length)>=2)
    {
       length=temp;
    }

     /*Change the size.*/
    SubductULLONG(&(directory->entry[index].e_size),directory->entry[index].e_size,length);/*Maybe the file become empty,however we should not delete the catalogue.*/
	if(IamaZeroULLONGEntity(directory->entry[index].e_size))  /*It become an empty file*/
	{
	   EMPTY pback;
	   pback.t_number.high=0;pback.t_number.low=1;
	   pback.t_type=PETAL_SINGLEEMPTY;
	   pback.t_startcluster=(directory->entry[index]).e_startcluster;
	   ResumeCluster(&pback);
	   directory->entry[index].e_startcluster.high=PETAL_INVALID;
	   directory->entry[index].e_startcluster.low =PETAL_INVALID;
	}
	/*-------------------------------------------------------------------------------------------*/





	
	U4B filelistcontrol;FindFreeClusterControl(&filelistcontrol);
	PPETALFILE pfilelist=(PPETALFILE)FSControlToAddress(filelistcontrol);
	LoadCluster(directory->entry[index].e_startcluster,filelistcontrol);/*We have ensure that the startcluster is valid.*/
    SaveDefaultControl(directorycontrol);
    ReleaseControl(directorycontrol);


	
	ULLONG number;number.low=0;number.high=0;     
	for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*//*Why not consider the situation that it's an empty file .We have prohibit this .*/
	{
	    index++;
        AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index<0)  /*Maybe it's not used.*/
	{
	    ReleaseControl(filelistcontrol);
		return 1;
	}
	/*Ok,we now get the index,which contain the delete beginning.*/
	/*The offset*/
	U4B startindex=index;
	ULLONG startoffset;
	SubductULLONG(&startoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&startoffset,position,startoffset);
	
	AddULLONG(&temp,position,length);
    for(;CompareULLONG(temp,number)==1;) //not <= !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    {
      index++;
	  AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index>=126)
	{
	   ReleaseControl(filelistcontrol);
	   return 1;
	}
    /*Ok,we now get the index,which contain the delete end.*/
	U4B endindex=index;
	ULLONG endoffset;
	SubductULLONG(&endoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&endoffset,temp,endoffset);
	Assert(endindex>=startindex) /*to protect the fs*/
	/*--------------------------------------------------------------------------------*/
	/*
	     We sum up the variables now.
	     
	     startindex:      the index that the delete beginning in
	     startoffset:      the delete point relative to the clusters the index presents
	     endindex:        the index the end delete point
	     endoffset:       the offset relative to the end index
	     temp:             temporary ULLONG variable
	     number:         tempory ULLONG variable
	     pfilelist:          contain the file content pointer.
	*/
	
/*---------------------------------------------------------------------------------------------------------------------------------------*/

	
    U4B level=1;
	pfilelist->head.h_index=startindex;
    pfilelist->head.h_firstindex=startindex;
	pfilelist->head.h_firstoffset=startoffset;
	pfilelist->head.h_secondindex=endindex;
	pfilelist->head.h_secondoffset=endoffset;
    SaveDefaultControl(filelistcontrol);
	
    /*
            To increase the depth ,we should set the header,when decrease the depth ,we should fetch the header.
            The header is about the current level,it have a item "upper",it point to the previous level.
	*/
	
	while(1)
	{		
	   if(level==0)
	   {
	      ReleaseControl(filelistcontrol);
	      return 0;
	   }
	   if(pfilelist->head.h_index>pfilelist->head.h_secondindex)
	   {
	      /*here should decide whether the cluster is empty.*/
		  S4B i;		  
		  for(i=0;i<126;i++)
		  {
             if(pfilelist->section[i].f_type!=PETAL_INVALID)
             {
                break;
             }
		  }
		  if(i!=126)
		  {
	         SaveDefaultControl(filelistcontrol);
	         LoadCluster(pfilelist->head.h_upper,filelistcontrol);
		     level--;
		     continue;
		  }
		  else
		  {
		     EMPTY pback;
			 pback.t_number.high=0;pback.t_number.low=1;
			 pback.t_startcluster=fscontrol[filelistcontrol].fromcluster;
			 pback.t_type=PETAL_SINGLEEMPTY;
			 ResumeCluster(&pback);			 
		     LoadCluster(pfilelist->head.h_upper,filelistcontrol);
			 level--;
			 continue;
		  }
	   }
	   

	   index=pfilelist->head.h_index;	 
	   
	   if(pfilelist->head.h_firstindex==pfilelist->head.h_index)
	   {  
		   startoffset=pfilelist->head.h_firstoffset;
	   }
	   else
	   {
	       startoffset.low=0;
		   startoffset.high=0;
	   }
	   if(pfilelist->head.h_index==pfilelist->head.h_secondindex)
	   {
	       endoffset=pfilelist->head.h_secondoffset;
		   if(CompareULLONG(endoffset,pfilelist->section[pfilelist->head.h_index].f_size)==1)/*Protect the file*/
		   {
		      endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
		   }
	   }
	   else
	   {
	     endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
	   }



       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_INVALID)
       {
          pfilelist->head.h_index++;
		  continue;
       }

	   if(startoffset.low==endoffset.low && startoffset.high==endoffset.high)
	   {
	      pfilelist->head.h_index++;
		  continue;
	   }
	   
       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTENT)
       {
          SubductULLONG(&temp,endoffset,startoffset);
		  if(CompareULLONG(temp,pfilelist->section[pfilelist->head.h_index].f_size)<=1) /*temp>=size*/
		  {
		     EMPTY  pback;
			 pback.t_number.low=1;
			 pback.t_number.high=0;
			 pback.t_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
			 pback.t_type=PETAL_SINGLEEMPTY;
			 ResumeCluster(&pback);
			 pfilelist->section[pfilelist->head.h_index].f_size.low=0;
			 pfilelist->section[pfilelist->head.h_index].f_size.high=0;
			 pfilelist->section[pfilelist->head.h_index].f_startcluster.low=PETAL_INVALID;
			 pfilelist->section[pfilelist->head.h_index].f_startcluster.high=PETAL_INVALID;
			 pfilelist->section[pfilelist->head.h_index].f_type=PETAL_INVALID;			 
			 pfilelist->head.h_index++;
			 continue;
		  }
		  else
		  {
		     U4B   contentcontrol;FindFreeClusterControl(&contentcontrol);
			 PU1B  pcontent      =(PU1B)FSControlToAddress(contentcontrol);
			 LoadCluster(pfilelist->section[pfilelist->head.h_index].f_startcluster,contentcontrol);
			 PU1B  destination=pcontent+startoffset.low;
			 PU1B  source     =pcontent+endoffset.low;
			 PU1B  end        =pcontent+pfilelist->section[pfilelist->head.h_index].f_size.low;
			 for(;source<end;source++,destination++)
			 {
			    *destination=*source;
			 }
			 SaveDefaultControl(contentcontrol);			 
			 ReleaseControl(contentcontrol);
			 SubductULLONG(&temp,endoffset,startoffset);
			 SubductULLONG(&(pfilelist->section[pfilelist->head.h_index].f_size),pfilelist->section[pfilelist->head.h_index].f_size,temp);
			 pfilelist->head.h_index++;
			 continue;
		  }
		  
       }


	   /*----------------------------------------------------------------------------------------------------------------------*/
	   if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTINUOUS)
	   {
	      if(IamaZeroULLONGEntity(startoffset))
	      {
	         ULLONG q;
	         DivideULLONGU4B(&q,&temp,endoffset,sizeof(CLUSTER));/*In front ,we make sure that endoffset!=startoffset.*/
			 if(IamaZeroULLONGEntity(temp))
			 {
			    EMPTY pback;
				pback.t_number=q;
				pback.t_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
				if(q.low==1 && q.high==0) /*q==1*/
				{
				  pback.t_type=PETAL_SINGLEEMPTY;
				}
				else
			    {
			       pback.t_type=PETAL_CONTINUOUSEMPTY;
				}
				ResumeCluster(&pback);
				AddULLONG(&(pfilelist->section[pfilelist->head.h_index].f_startcluster),pfilelist->section[pfilelist->head.h_index].f_startcluster,q);
				SubductULLONG(&temp,endoffset,startoffset);
				SubductULLONG(&(pfilelist->section[pfilelist->head.h_index].f_size),pfilelist->section[pfilelist->head.h_index].f_size,temp);/*Change the size*/
				if(pfilelist->section[pfilelist->head.h_index].f_size.low==0 && pfilelist->section[pfilelist->head.h_index].f_size.high==0)
				{
				   pfilelist->section[pfilelist->head.h_index].f_type=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.high=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.low=PETAL_INVALID;
				}
				else
				{
                   if(CompareULLONGU4B(pfilelist->section[pfilelist->head.h_index].f_size,sizeof(CLUSTER))==1)
                   {
                      pfilelist->section[pfilelist->head.h_index].f_type=PETAL_CONTINUOUS;
                   }
				   else
				   {
				      pfilelist->section[pfilelist->head.h_index].f_type=PETAL_CONTENT;
				   }
				}
				pfilelist->head.h_index++;
				continue;
			 }		 
	      }


		  

          if(endoffset.high==pfilelist->section[pfilelist->head.h_index].f_size.high && endoffset.low==pfilelist->section[pfilelist->head.h_index].f_size.low)
          {
             ULLONG remain;
             DivideULLONGU4B(&temp,&remain,startoffset,sizeof(CLUSTER));
			 if(IamaZeroULLONGEntity(remain))
			 {
			    EMPTY p;
				ULLONG t;
				SubductULLONG(&t,endoffset,startoffset);
				SubductULLONG(&(pfilelist->section[pfilelist->head.h_index].f_size),pfilelist->section[pfilelist->head.h_index].f_size,t);/*Change the size*/
				ULLONG r;
				DivideULLONGU4B(&t,&r,t,sizeof(CLUSTER));
				p.t_number=t;
				AddULLONG(&(p.t_startcluster),pfilelist->section[pfilelist->head.h_index].f_startcluster,temp);
				if(CompareULLONGU4B(t,1)==1)
				{p.t_type=PETAL_CONTINUOUSEMPTY;}
				else
				{p.t_type=PETAL_SINGLEEMPTY;}
				ResumeCluster(&p);
				if(pfilelist->section[pfilelist->head.h_index].f_size.low==0 && pfilelist->section[pfilelist->head.h_index].f_size.high==0)
				{
				   pfilelist->section[pfilelist->head.h_index].f_type=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.high=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.low=PETAL_INVALID;
				}
				else
				{
                   if(CompareULLONGU4B(pfilelist->section[pfilelist->head.h_index].f_size,sizeof(CLUSTER))==1)
                   {
                      pfilelist->section[index].f_type=PETAL_CONTINUOUS;
                   }
				   else
				   {
				      pfilelist->section[index].f_type=PETAL_CONTENT;
				   }
				}
				pfilelist->head.h_index++;
				continue;
			 }
          }





          U4B extendcontrol;FindFreeClusterControl(&extendcontrol);
		  ULLONG nextlevel=pfilelist->head.h_level;
		  AddULLONGU4B(&nextlevel,nextlevel,1);
		  InitFileBuffer(extendcontrol,fscontrol[filelistcontrol].fromcluster,pfilelist->head.h_index,nextlevel);
		  ULLONG extendcluster;
		  ApplyForACluster(&extendcluster);
		  BindControlCluster(extendcontrol,extendcluster);
		  PPETALFILE pextend=(PPETALFILE)FSControlToAddress(extendcontrol);
		  
          /*----------------------------------0--------------------------------------------*/
          if(CompareULLONGU4B(startoffset,2*sizeof(CLUSTER))<=1)/*startoffset>=2*sizeof(CLUSTER)*/
          {
                pextend->section[0].f_type=PETAL_CONTINUOUS;
				ULLONG r;
				DivideULLONGU4B(&temp,&r,startoffset,sizeof(CLUSTER));
				MultiplyULLONGU4B(&(pextend->section[0].f_size),temp,sizeof(CLUSTER));
				pextend->section[0].f_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
          }
		  else
		  {
		     if(CompareULLONGU4B(startoffset,sizeof(CLUSTER))<=1)
		     {
		        pextend->section[0].f_type=PETAL_CONTENT;
				pextend->section[0].f_size.low=sizeof(CLUSTER);
				pextend->section[0].f_size.high=0;
				pextend->section[0].f_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
             }
			 else
			 {
			    pextend->section[0].f_size.high=0;pextend->section[0].f_size.low=0;
				pextend->section[0].f_startcluster.high=0;
				pextend->section[0].f_startcluster.low =0;
				pextend->section[0].f_type=PETAL_INVALID;
			 }
		  }

          /*----------------------------------1-------------------------------------------*/
		  
		  pextend->section[1].f_type=PETAL_CONTENT;
		  pextend->section[1].f_size.high=0;pextend->section[1].f_size.low=sizeof(CLUSTER);
		  pextend->head.h_firstindex=1;
		  pextend->head.h_index=1;
          if(pextend->section[0].f_type==PETAL_INVALID)
          {
             pextend->head.h_firstoffset=startoffset;
             pextend->section[1].f_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
          }
		  else
		  {
		     ULLONG t,r;
			 DivideULLONGU4B(&t,&r,pextend->section[0].f_size,sizeof(CLUSTER));
			 AddULLONG(&t,pextend->section[0].f_startcluster,t);
			 pextend->section[1].f_startcluster=t;
			 SubductULLONG(&(pextend->head.h_firstoffset),startoffset,pextend->section[0].f_size);
		  }
		  /*---------------------------------2----------------------------------------------*/
          ULLONG t,r,m;
		  DivideULLONGU4B(&t,&r,endoffset,sizeof(CLUSTER));
		  DivideULLONGU4B(&temp,&r,startoffset,sizeof(CLUSTER));
		  SubductULLONG(&m,t,temp);
		  if(CompareULLONGU4B(m,2)==1)
		  {
		     SubductULLONGU4B(&m,m,1);
		     MultiplyULLONGU4B(&(pextend->section[2].f_size),m,sizeof(CLUSTER));
			 AddULLONGU4B(&(pextend->section[2].f_startcluster),pextend->section[1].f_startcluster,1);
			 pextend->section[2].f_type=PETAL_CONTINUOUS;
		  }
		  else
		  {
		     if(CompareULLONGU4B(m,2)==0)/*Only one */
		     {
		        pextend->section[2].f_size.high=0;pextend->section[2].f_size.low=sizeof(CLUSTER);
				AddULLONGU4B(&(pextend->section[2].f_startcluster),pextend->section[1].f_startcluster,1);
				pextend->section[2].f_type=PETAL_CONTENT;
		     }
			 else/*invalid*/
			 {
			    pextend->section[2].f_size.low=0;pextend->section[2].f_size.high=0;
				pextend->section[2].f_startcluster.high=PETAL_INVALID;
				pextend->section[2].f_startcluster.low=PETAL_INVALID;
				pextend->section[2].f_type=PETAL_INVALID;
			 }
		  }
        /*----------------------------------3--------------------------------------------------*/
		pextend->head.h_secondindex=3;
		DivideULLONGU4B(&t,&r,endoffset,sizeof(CLUSTER));
		DivideULLONGU4B(&temp,&r,startoffset,sizeof(CLUSTER));
	    SubductULLONG(&m,t,temp);
		if(IamaZeroULLONGEntity(m))
		{
		   pextend->section[3].f_type=PETAL_INVALID;
		   pextend->section[3].f_size.low=0;pextend->section[3].f_size.high=0;
		   pextend->section[3].f_startcluster.high=PETAL_INVALID;
		   pextend->section[3].f_startcluster.low =PETAL_INVALID;
		   pextend->head.h_secondindex=pextend->head.h_firstindex;
		   SubductULLONG(&(pextend->head.h_secondoffset),endoffset,pextend->section[0].f_size);
		}
		else
		{
		   pextend->section[3].f_type=PETAL_CONTENT;
		   pextend->section[3].f_size.high=0;pextend->section[3].f_size.low=sizeof(CLUSTER);
		   if(pextend->section[2].f_type==PETAL_INVALID)
		   {
		      AddULLONGU4B(&(pextend->section[3].f_startcluster),pextend->section[1].f_startcluster,1);
		   }
		   else
		   {
			  AddULLONG(&(pextend->section[3].f_startcluster),pfilelist->section[index].f_startcluster,t);
		   }
		   SubductULLONG(&(pextend->head.h_secondoffset),endoffset                     ,pextend->section[0].f_size);
		   SubductULLONG(&(pextend->head.h_secondoffset),(pextend->head.h_secondoffset),pextend->section[1].f_size);
		   SubductULLONG(&(pextend->head.h_secondoffset),(pextend->head.h_secondoffset),pextend->section[2].f_size);
		}
		/*----------------------------------4-------------------------------------------------------*/
		DivideULLONGU4B(&m,&r,pfilelist->section[index].f_size,sizeof(CLUSTER));
		SubductULLONGU4B(&t,m,1); 
		ULLONG n;
		AddULLONG(&n,pfilelist->section[index].f_startcluster,t);
		/*t:the cluster offset relative to the start cluster.*/
		/*n:the last    cluster.*/
		/*r:the content offset relative to the last cluster.*/
		if(pextend->section[3].f_type==PETAL_INVALID) /*if this take effects,then the section[2] is PETAL_INVALID*/
		{
		   if(CompareULLONG(pextend->section[1].f_startcluster,n)==0) 
		   {
		      pextend->section[4].f_type=PETAL_INVALID;
			  pextend->section[4].f_size.low=0;pextend->section[4].f_size.high=0;
			  pextend->section[4].f_startcluster.high=PETAL_INVALID;
			  pextend->section[4].f_startcluster.low =PETAL_INVALID;
		   }
		   else
		   {
		      SubductULLONG(&m,n,pextend->section[1].f_startcluster);
			  /*m:the number of cluster after the last cluster.*/
			  if(CompareULLONGU4B(m,2)<2)/*m>=2*/
			  {
			     pextend->section[4].f_type=PETAL_CONTINUOUS;
				 AddULLONGU4B(&(pextend->section[4].f_startcluster),(pextend->section[1].f_startcluster),1);
			     MultiplyULLONGU4B(&(pextend->section[4].f_size),m,sizeof(CLUSTER));
			  }
			  else
			  {
			     if(CompareULLONGU4B(m,1)==0) /*m==1*/
			     {
			       pextend->section[4].f_type=PETAL_CONTENT;
				   AddULLONGU4B(&(pextend->section[4].f_startcluster),(pextend->section[1].f_startcluster),1);
			       MultiplyULLONGU4B(&(pextend->section[4].f_size),m,sizeof(CLUSTER));
				 }
				 else
				 {
				   pextend->section[4].f_type=PETAL_INVALID;
				   pextend->section[4].f_startcluster.low=PETAL_INVALID;
				   pextend->section[4].f_startcluster.high=PETAL_INVALID;
				   pextend->section[4].f_size.low=0;
				   pextend->section[4].f_size.high=0;
				 }

			  }
		   }
		}
		else
		{
			if(CompareULLONG(pextend->section[3].f_startcluster,n)==0)
			{
			   pextend->section[4].f_type=PETAL_INVALID;
			   pextend->section[4].f_size.low=0;pextend->section[4].f_size.high=0;
			   pextend->section[4].f_startcluster.high=PETAL_INVALID;
			   pextend->section[4].f_startcluster.low =PETAL_INVALID;
			}
			else
			{
			   SubductULLONG(&m,n,pextend->section[3].f_startcluster);
			   /*m:the number of the remain cluster.*/
			   if(CompareULLONGU4B(m,2)<2)/*m>=2*/
			   {
				  pextend->section[4].f_type=PETAL_CONTINUOUS;
			   }
			   else
			   {
				  pextend->section[4].f_type=PETAL_CONTENT;
			   }
			   AddULLONGU4B(&(pextend->section[4].f_startcluster),(pextend->section[3].f_startcluster),1);
			   MultiplyULLONGU4B(&(pextend->section[4].f_size),m,sizeof(CLUSTER));
			} 
		}
        pfilelist->head.h_index++;
		SubductULLONG(&temp,endoffset,startoffset);
		SubductULLONG(&(pfilelist->section[index].f_size),(pfilelist->section[index].f_size),temp);
		pfilelist->section[index].f_startcluster=extendcluster;
		pfilelist->section[index].f_type=PETAL_EXTENDED;
		if(CompareULLONGU4B(pfilelist->section[index].f_size,0)==0)
		{
		    EMPTY pback;
			pback.t_number.high=0;pback.t_number.low=1;
			pback.t_startcluster=pfilelist->section[index].f_startcluster;
			pback.t_type=PETAL_SINGLEEMPTY;
			ResumeCluster(&pback);
			pfilelist->section[index].f_startcluster.low=PETAL_INVALID;
			pfilelist->section[index].f_startcluster.high=PETAL_INVALID;
			pfilelist->section[index].f_type=PETAL_INVALID;
		}
        SaveDefaultControl(filelistcontrol);
		U4B swap=filelistcontrol;
		filelistcontrol=extendcontrol;
		extendcontrol=swap;
		pfilelist=(PPETALFILE)FSControlToAddress(filelistcontrol);
		ReleaseControl(extendcontrol);
		level++;
		continue;
       }

/*-----------------------------------------------------------------------------------------------------------------*/
       if(pfilelist->section[index].f_type==PETAL_EXTENDED)
       {
          ULLONG size;
		  SubductULLONG(&size,endoffset,startoffset);
		  SubductULLONG(&(pfilelist->section[index].f_size),(pfilelist->section[index].f_size),size);
		  if(pfilelist->section[index].f_size.high==0 && pfilelist->section[index].f_size.low==0)
		  {
		     pfilelist->section[index].f_type=PETAL_INVALID;
			 pfilelist->head.h_index++;
			 ULLONG next;
			 next=pfilelist->section[index].f_startcluster;
			 pfilelist->section[index].f_startcluster.low=PETAL_INVALID;
			 pfilelist->section[index].f_startcluster.high=PETAL_INVALID;
			 SaveDefaultControl(filelistcontrol);
			 
			 LoadCluster(next,filelistcontrol);
			 pfilelist->head.h_firstindex=0;
			 pfilelist->head.h_firstoffset.low=0;
			 pfilelist->head.h_index=0;
			 pfilelist->head.h_secondindex=125;
			 pfilelist->head.h_secondoffset=pfilelist->section[pfilelist->head.h_secondindex].f_size;
			 level++;
			 continue;
		  }

          pfilelist->head.h_index++;
          SaveDefaultControl(filelistcontrol);
          LoadCluster(pfilelist->section[index].f_startcluster,filelistcontrol);


       
	      number.low=0;number.high=0;	 
	      position=startoffset;
	   
	      for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*//*Why not consider the situation that it's an empty file .We have prohibit this .*/
	      {
		      index++;
		      AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete beginning.*/
	      /*The offset*/
	      pfilelist->head.h_firstindex=index;
	      pfilelist->head.h_index=index;
	      SubductULLONG(&(pfilelist->head.h_firstoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_firstoffset),position,pfilelist->head.h_firstoffset);
	   
	      temp=endoffset;
	      for(;CompareULLONG(temp,number)<=1;)
	      {
		    index++;
		    AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete end.*/
	      pfilelist->head.h_secondindex=index;
	      SubductULLONG(&(pfilelist->head.h_secondoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_secondoffset),temp,pfilelist->head.h_secondoffset);
          level++;
	      continue;
       }
		  
		  
    }
	ReleaseControl(filelistcontrol);
	return 0;
}

PUBLIC S4B DeleteDirectory(PCHAR path)
{
   U4B directorytype=PETAL_FILE;
   FSPathType(path,&directorytype);
   if(directorytype==PETAL_FILE)
   {
       ULLONG deletefrom,length;
	   deletefrom.low=0;deletefrom.high=0;length.low=0xFFFFFFFF;length.high=0xFFFFFFFF;
       DeleteFileContent(path,deletefrom ,length);
   }
   ULLONG directorycluster;
   U4B    directoryindex;
   if(LocateDirectory(path,&directorycluster,&directoryindex)!=0) /*not find.*/
       return 1;
   U4B directorycontrol=0;FindFreeClusterControl(&directorycontrol);
   PPETALDIRECTORY pdirectory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
   LoadCluster(directorycluster,directorycontrol);
   if(!(IamaInvalidULLONGEntity(pdirectory->entry[directoryindex].e_startcluster))) /*the file not empty or the  directory not empty*/
        return 1;
   MemorySet((PVOID)(&(pdirectory->entry[directoryindex])),sizeof(DIRECTORYITEM),0);
   pdirectory->entry[directoryindex].e_type=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_startcluster.low=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_startcluster.high=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_size.low=0;
   pdirectory->entry[directoryindex].e_size.high=0;
   


   U4B upperdirectorycontrol;FindFreeClusterControl(&upperdirectorycontrol);
   PPETALDIRECTORY pupperdirectory=(PPETALDIRECTORY)FSControlToAddress(upperdirectorycontrol);
   LoadCluster(pdirectory->linker.l_upper,upperdirectorycontrol);
   SubductULLONGU4B(
           &(pupperdirectory->entry[pdirectory->linker.l_upperindex].e_size),
           pupperdirectory->entry[pdirectory->linker.l_upperindex].e_size,
           1); /*the item number decrease.*/
   
   directoryindex=0;
   for(;directoryindex<31;directoryindex++)
   {
       if(pdirectory->entry[directoryindex].e_type!=PETAL_INVALID)
	      break;
   }
   if(directoryindex<31)
   {
       SaveDefaultControl(upperdirectorycontrol);
	   SaveDefaultControl(directorycontrol);
	   ReleaseControl(upperdirectorycontrol);
	   ReleaseControl(directorycontrol);
	   return 0;
   }
   /*this directory cluster is empty now .Release it.*/
   
       EMPTY pback;
	   pback.t_type=PETAL_SINGLEEMPTY;
	   pback.t_startcluster=fscontrol[directorycontrol].fromcluster;
	   pback.t_number.low=1;pback.t_number.high=0;
	   ResumeCluster(&pback);
	   
       if(IamaZeroULLONGEntity(pdirectory->linker.l_previous)) /*this is the first cluster*/
	   {
		   pupperdirectory->entry[pdirectory->linker.l_upperindex].e_startcluster=pdirectory->linker.l_next;
	   }
       else
	   {
	       U4B previouscontrol;FindFreeClusterControl(&previouscontrol);
		   PPETALDIRECTORY pprevious=(PPETALDIRECTORY)FSControlToAddress(previouscontrol);
		   LoadCluster(pdirectory->linker.l_previous,previouscontrol);
		   pprevious->linker.l_next=pdirectory->linker.l_next;
		   SaveDefaultControl(previouscontrol);
		   ReleaseControl(previouscontrol);
	   }
   SaveDefaultControl(upperdirectorycontrol);
   /*because we have released the current directory cluster ,so we need not save it.*/
   ReleaseControl(upperdirectorycontrol);
   ReleaseControl(directorycontrol);
   return 0;
}

PUBLIC S4B ReadFileContent(PU1B destination,PULLONG pactuallength,PCHAR path,ULLONG position,ULLONG length)
{
   /*Make sure that we want to read something in a file ,not others*/
    U4B filetype=0;FSPathType(path,&filetype);
    if(filetype!=PETAL_FILE)
      return 1;
	/*------------------------------------------------------------------------------------*/
   /*Loacate the directory cluster.*/
    ULLONG cluster;
    S4B    index;
   
    if( LocateDirectory(path,&cluster,(PU4B)(&index))!=0)
		return 1;

    if(IamaZeroULLONGEntity(length))
	{
	   pactuallength->low=0;pactuallength->high=0;
	   return 0;
	}

	
    U4B        directorycontrol;
	FindFreeClusterControl(&directorycontrol);
    PPETALDIRECTORY directory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
	LoadCluster(cluster,directorycontrol);

    /*Maybe ,this sentence is not necessary .However each step is independent.^_^*/
    if(directory->entry[index].e_type!=PETAL_FILE)
    {ReleaseControl(directorycontrol);return 1;}

	/*Maybe ,the directory has no cluster.*/
    if(directory->entry[index].e_startcluster.high==PETAL_INVALID && directory->entry[index].e_startcluster.low==PETAL_INVALID)
    {
      directory->entry[index].e_size.high=0;directory->entry[index].e_size.low=0;
	  SaveDefaultControl(directorycontrol);
      ReleaseControl(directorycontrol);
	  pactuallength->low=0;pactuallength->high=0;
	  return 0;
    }
	
	/*position>=size,if it's an empty file ,size=0,so the position must >=size,so return.read from the end of the file,it's so funny.*/ 
    if(CompareULLONG(position,directory->entry[index].e_size)<=1)
    {
        ReleaseControl(directorycontrol);
		pactuallength->low=0;pactuallength->high=0;
        return 0;
    }
	/*To protect the file.*/
    *pactuallength=length;
    ULLONG temp;
    SubductULLONG(&temp,directory->entry[index].e_size,position);
    if(CompareULLONG(temp,length)>=2)
    {
       length=temp;
	   *pactuallength=length;
    }

	/*-------------------------------------------------------------------------------------------*/
	
	U4B filelistcontrol;FindFreeClusterControl(&filelistcontrol);
	PPETALFILE pfilelist=(PPETALFILE)FSControlToAddress(filelistcontrol);
	LoadCluster(directory->entry[index].e_startcluster,filelistcontrol);/*We have ensure that the startcluster is valid.*/
    ReleaseControl(directorycontrol);
	
	ULLONG number;number.low=0;number.high=0;     
	for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*//*Why not consider the situation that it's an empty file .We have prohibit this .*/
	{
	    index++;
        AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index<0)  /*Maybe it's not used.*/
	{
	    ReleaseControl(filelistcontrol);
		return 1;
	}
	/*Ok,we now get the index,which contain the read beginning.*/
	/*The offset*/
	U4B startindex=index;
	ULLONG startoffset;
	SubductULLONG(&startoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&startoffset,position,startoffset);
	
	AddULLONG(&temp,position,length);
    for(;CompareULLONG(temp,number)<=1;)
    {
      index++;
	  AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index>=126)
	{
	   ReleaseControl(filelistcontrol);
	   pactuallength->low=0;
	   pactuallength->high=0;
	   return 1;/*there must be something wrong with this file.*/
	}
    /*Ok,we now get the index,which contain the read end.*/
	U4B endindex=index;
	ULLONG endoffset;
	SubductULLONG(&endoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&endoffset,temp,endoffset);
	Assert(endindex>=startindex) /*to protect the fs*/
	/*--------------------------------------------------------------------------------*/
	/*
	     We sum up the variables now.
	     
	     startindex:      the index that the delete beginning in
	     startoffset:      the delete point relative to the clusters the index presents
	     endindex:        the index the end delete point
	     endoffset:       the offset relative to the end index
	     temp:             temporary ULLONG variable
	     number:         tempory ULLONG variable
	     pfilelist:          contain the file content pointer.
	*/
	
/*---------------------------------------------------------------------------------------------------------------------------------------*/

	
    U4B level=1;
	pfilelist->head.h_index=startindex;
    pfilelist->head.h_firstindex=startindex;
	pfilelist->head.h_firstoffset=startoffset;
	pfilelist->head.h_secondindex=endindex;
	pfilelist->head.h_secondoffset=endoffset;
    SaveDefaultControl(filelistcontrol);
	
    /*
            To increase the depth ,we should set the header,when decrease the depth ,we should fetch the header.
            The header is about the current level,it have a item "upper",it point to the previous level.
	*/
	
	while(1)
	{		
	   if(level==0)
	   {
	      ReleaseControl(filelistcontrol);
	      return 0;
	   }
	   if(pfilelist->head.h_index>pfilelist->head.h_secondindex)
	   {
	     
	         LoadCluster(pfilelist->head.h_upper,filelistcontrol);
		     level--;
		     continue;
	   }
	   
	   index=pfilelist->head.h_index;	 
	   
	   if(pfilelist->head.h_firstindex==pfilelist->head.h_index)
	   {  
		   startoffset=pfilelist->head.h_firstoffset;
	   }
	   else
	   {
	       startoffset.low=0;
		   startoffset.high=0;
	   }
	   if(pfilelist->head.h_index==pfilelist->head.h_secondindex)
	   {
	       endoffset=pfilelist->head.h_secondoffset;
		   if(CompareULLONG(endoffset,pfilelist->section[pfilelist->head.h_index].f_size)==1)/*Protect the file*/
		   {
		      endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
		   }
	   }
	   else
	   {
	     endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
	   }



       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_INVALID
	      || IamaZeroULLONGEntity(pfilelist->section[pfilelist->head.h_index].f_size))
       {
          pfilelist->head.h_index++;
		  continue;
       }

	   if(startoffset.low==endoffset.low && startoffset.high==endoffset.high)
	   {
	      pfilelist->head.h_index++;
		  continue;
	   }
	   //-----------2012.4.3 in the library.Oh,My God ,I need a computer.--------------------------------------------------------------
       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTENT)
       {
	      U4B contentcontrol;
		  FindFreeClusterControl(&contentcontrol);
		  PU1B pcontent=(PU1B)FSControlToAddress(contentcontrol);
		  LoadCluster(pfilelist->section[pfilelist->head.h_index].f_startcluster,contentcontrol);
          U4B number=endoffset.low-startoffset.low;
		  
          MemoryCopy((PCHAR)destination,(PCHAR)((PCHAR)pcontent+startoffset.low),number);
		  destination+=(number);
		  ReleaseControl(contentcontrol);
	      pfilelist->head.h_index++;
		  continue;	  
       }


	   /*-------------------------------2012.4.3.9.26-----------------------------------------------------------------------*/
	   if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTINUOUS)
       {
	       ULLONG firstcluster,lastcluster,firstoffset,lastoffset;
		   DivideULLONGU4B(&firstcluster,&firstoffset,startoffset,sizeof(CLUSTER));
		   AddULLONG(&firstcluster,firstcluster,pfilelist->section[pfilelist->head.h_index].f_startcluster);
		   DivideULLONGU4B(&lastcluster, &lastoffset, endoffset,  sizeof(CLUSTER));
		   AddULLONG(&lastcluster,lastcluster,pfilelist->section[pfilelist->head.h_index].f_startcluster);
		   /*
		       firstcluster:the first cluster we should read
			   firstoffset :the offset relative to the firstcluster.
			   lastcluster :......
			   lastoffset  :......  
		   */
		   ULLONG i=firstcluster;
		   U4B readstart;
           U4B readend;	
		   U4B contentcontrol;
		   FindFreeClusterControl(&contentcontrol);
		   PU1B pcontent=(PU1B)FSControlToAddress(contentcontrol);

		   for(;CompareULLONG(lastcluster,i)<2;AddULLONGU4B(&i,i,1))
		   {
		       if(i.low==firstcluster.low && i.high==firstcluster.high)
			   {readstart=firstoffset.low;}
			   else
			   {readstart=0;}
			   
			   if(i.low==lastcluster.low && i.high==lastcluster.high)
			   {readend=lastoffset.low;}
			   else
			   {readend=sizeof(CLUSTER);}
			   
			   LoadCluster(i,contentcontrol);
			   
			   PU1B readpointer=pcontent+readstart;
			   for(;readpointer<(pcontent+readend);readpointer++)
			   {
			       *destination=*readpointer;
				   destination++;
			   }
			   
		   }
		   ReleaseControl(contentcontrol);
	       pfilelist->head.h_index++;
		   continue;
	   }
/*-----------------------------------------------------------------------------------------------------------------*/
       if(pfilelist->section[index].f_type==PETAL_EXTENDED)
       {
          

          pfilelist->head.h_index++;
          SaveDefaultControl(filelistcontrol);
          LoadCluster(pfilelist->section[index].f_startcluster,filelistcontrol);


       
	      number.low=0;number.high=0;	 
	      position=startoffset;
	   
	      for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*/
	      {
		      index++;
		      AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete beginning.*/
	      /*The offset*/
	      pfilelist->head.h_firstindex=index;
	      pfilelist->head.h_index=index;
	      SubductULLONG(&(pfilelist->head.h_firstoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_firstoffset),position,pfilelist->head.h_firstoffset);
	   
	      temp=endoffset;
	      for(;CompareULLONG(temp,number)<=1;)
	      {
		    index++;
		    AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete end.*/
	      pfilelist->head.h_secondindex=index;
	      SubductULLONG(&(pfilelist->head.h_secondoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_secondoffset),temp,pfilelist->head.h_secondoffset);
          level++;
	      continue;
       }
		  
	   pfilelist->head.h_index++;  /*this sentence is important .Because there may be some wrong with the file system.*/
    }
	ReleaseControl(filelistcontrol);
   
   return 0;
}

PUBLIC S4B ReadDirectoryContent(PCHAR path,PDIRECTORYITEM pd,PULLONG plocation,PU4B pindex)
{
   MemorySet((PVOID)pd,sizeof(DIRECTORYITEM),0);
   plocation->high=0;plocation->low=0;
   *pindex=0;
   ULLONG locationcluster;
   U4B    locationindex;
   if(LocateDirectory(path,&locationcluster,&locationindex)!=0)
   {return 1;}
   *plocation=locationcluster;
   *pindex=locationindex;
   U4B directorycontrol=0;
   FindFreeClusterControl(&directorycontrol);
   PPETALDIRECTORY pdirectory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
   LoadCluster(locationcluster,directorycontrol);
   *pd=pdirectory->entry[locationindex];
   ReleaseControl(directorycontrol);
    return 0;
}








/*-------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------*/
/*Before ,there are many functions are useful,but now ,I needn't them.I need the function which operate the 
 opened files or directories.So I rewrite them,and I reserve them for future.*/

PUBLIC S4B CreateDirectory        (PFILEDESCRIPTOR pdescriptor)
{
   return 
     CreateFileAndFolder(
	                     (PCHAR)    ((pdescriptor->path)),
	                     (PULLONG)  (&(pdescriptor->location)),
						 (PU4B)     (&(pdescriptor->index))
						 );
}
PUBLIC S4B CreateFile             (PFILEDESCRIPTOR pdescriptor)
{
    
    return 
	   CreateFileAndFolder(
	                        (PCHAR)      ((pdescriptor->path)),
							(PULLONG)    (&(pdescriptor->location)),
							(PU4B)       (&(pdescriptor->index))
						  );
}
PUBLIC S4B OpenFile               (PFILEDESCRIPTOR pdescriptor)
{
  // Print("%X",pdescriptor->);
   return 
      LocateDirectory(
	                  (PCHAR)     (pdescriptor->path),
					  (PULLONG)   (&(pdescriptor->location)),
					  (PU4B)      (&(pdescriptor->index))
					  );
}
PUBLIC S4B OpenDirectory          (PFILEDESCRIPTOR pdescriptor)
{
      return
     	 LocateDirectory(
		                 (PCHAR)    (pdescriptor->path),
						 (PULLONG)  (&(pdescriptor->location)),
						 (PU4B)     (&(pdescriptor->index))
						 );
}
PUBLIC S4B DeleteOpenedFileContent(PFILEDESCRIPTOR pdescriptor)
{
	ULLONG position=pdescriptor->where;
	ULLONG length=pdescriptor->howmany;
    
   
    ULLONG cluster=pdescriptor->location;
    S4B    index=(S4B)(pdescriptor->index); /*Why not U4B ,just because the following give -1 to it.*/

	/*------------------------------------------------------------------------------------*/

	
    U4B        directorycontrol=0;
	FindFreeClusterControl(&directorycontrol);
    PPETALDIRECTORY directory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
	LoadCluster(cluster,directorycontrol);

    /*Maybe ,this sentence is not necessary .However each step is independent.^_^*/
    if(directory->entry[index].e_type!=PETAL_FILE)
    {ReleaseControl(directorycontrol);return 1;}

	/*Maybe ,the directory has no cluster.*/
    if(IamaInvalidULLONGEntity(directory->entry[index].e_startcluster))
    {
      directory->entry[index].e_size.high=0;directory->entry[index].e_size.low=0;
	  SaveDefaultControl(directorycontrol);
      ReleaseControl(directorycontrol);return 1;
    }
	
	/*position>=size,if it's an empty file ,size=0,so the position must >=size,so return.delete from the end of the file,it's so funny.*/ 
    if(CompareULLONG(position,directory->entry[index].e_size)<=1)
    {
        ReleaseControl(directorycontrol);
        return 0;
    }
	
	/*To protect the file.*/
    ULLONG temp;
    SubductULLONG(&temp,directory->entry[index].e_size,position);
    if(CompareULLONG(temp,length)>=2)
    {
       length=temp;
    }

     /*Change the size.*/
    SubductULLONG(&(directory->entry[index].e_size),directory->entry[index].e_size,length);/*Maybe the file become empty,however we should not delete the catalogue.*/
	if(IamaZeroULLONGEntity(directory->entry[index].e_size))  /*It become an empty file*/
	{
	   EMPTY pback;
	   pback.t_number.high=0;pback.t_number.low=1;
	   pback.t_type=PETAL_SINGLEEMPTY;
	   pback.t_startcluster=directory->entry[index].e_startcluster;
	   ResumeCluster(&pback);
	   directory->entry[index].e_startcluster.high=PETAL_INVALID;
	   directory->entry[index].e_startcluster.low =PETAL_INVALID;
	}
	/*-------------------------------------------------------------------------------------------*/


	
	U4B filelistcontrol=0;FindFreeClusterControl(&filelistcontrol);
	PPETALFILE pfilelist=(PPETALFILE)FSControlToAddress(filelistcontrol);
	LoadCluster(directory->entry[index].e_startcluster,filelistcontrol);/*We have ensure that the startcluster is valid.*/
    SaveDefaultControl(directorycontrol);
    ReleaseControl(directorycontrol);


	
	ULLONG number;number.low=0;number.high=0;     
	for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*//*Why not consider the situation that it's an empty file .We have prohibit this .*/
	{
	    index++;
        AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index<0)  /*Maybe it's not used.*/
	{
	    ReleaseControl(filelistcontrol);
		return 1;
	}
	/*Ok,we now get the index,which contain the delete beginning.*/
	/*The offset*/
	U4B startindex=index;
	ULLONG startoffset;
	SubductULLONG(&startoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&startoffset,position,startoffset);
	
	AddULLONG(&temp,position,length);
    for(;CompareULLONG(temp,number)<=1;)
    {
      index++;
	  AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index>=126)
	{
	   ReleaseControl(filelistcontrol);
	   return 1;
	}
    /*Ok,we now get the index,which contain the delete end.*/
	U4B endindex=index;
	ULLONG endoffset;
	SubductULLONG(&endoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&endoffset,temp,endoffset);
	Assert(endindex>=startindex) /*to protect the fs*/
	/*--------------------------------------------------------------------------------*/
	/*
	     We sum up the variables now.
	     
	     startindex:      the index that the delete beginning in
	     startoffset:      the delete point relative to the clusters the index presents
	     endindex:        the index the end delete point
	     endoffset:       the offset relative to the end index
	     temp:             temporary ULLONG variable
	     number:         tempory ULLONG variable
	     pfilelist:          contain the file content pointer.
	*/
	
/*---------------------------------------------------------------------------------------------------------------------------------------*/

	
    U4B level=1;
	pfilelist->head.h_index=startindex;
    pfilelist->head.h_firstindex=startindex;
	pfilelist->head.h_firstoffset=startoffset;
	pfilelist->head.h_secondindex=endindex;
	pfilelist->head.h_secondoffset=endoffset;
    SaveDefaultControl(filelistcontrol);
	
    /*
            To increase the depth ,we should set the header,when decrease the depth ,we should fetch the header.
            The header is about the current level,it have a item "upper",it point to the previous level.
	*/
	
	while(1)
	{		
	   if(level==0)
	   {
	      ReleaseControl(filelistcontrol);
	      return 0;
	   }
	   /*this level is end.*/
	   if(pfilelist->head.h_index>pfilelist->head.h_secondindex)
	   {
	      /*here should decide whether the cluster is empty.*/
		  S4B i;		  
		  for(i=0;i<126;i++)
		  {
             if(pfilelist->section[i].f_type!=PETAL_INVALID)
             {
                break;
             }
		  }
		  if(i!=126)
		  {
	         SaveDefaultControl(filelistcontrol);
	         LoadCluster(pfilelist->head.h_upper,filelistcontrol);
		     level--;
		     continue;
		  }
		  else
		  {
		     EMPTY pback;
			 pback.t_number.high=0;pback.t_number.low=1;
			 pback.t_startcluster=fscontrol[filelistcontrol].fromcluster;
			 pback.t_type=PETAL_SINGLEEMPTY;
			 ResumeCluster(&pback);			 
		     LoadCluster(pfilelist->head.h_upper,filelistcontrol);
			 level--;
			 continue;
		  }
	   }
	   

	   index=pfilelist->head.h_index;	 
	   
	   if(pfilelist->head.h_firstindex==pfilelist->head.h_index)
	   {  
		   startoffset=pfilelist->head.h_firstoffset;
	   }
	   else
	   {
	       startoffset.low=0;
		   startoffset.high=0;
	   }
	   if(pfilelist->head.h_index==pfilelist->head.h_secondindex)
	   {
	       endoffset=pfilelist->head.h_secondoffset;
		   if(CompareULLONG(endoffset,pfilelist->section[pfilelist->head.h_index].f_size)==1)/*Protect the file*/
		   {
		      endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
		   }
	   }
	   else
	   {
	     endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
	   }



       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_INVALID)
       {
          pfilelist->head.h_index++;
		  continue;
       }

	   if(startoffset.low==endoffset.low && startoffset.high==endoffset.high)
	   {
	      pfilelist->head.h_index++;
		  continue;
	   }
	   
       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTENT)
       {
          SubductULLONG(&temp,endoffset,startoffset);
		  if(CompareULLONG(temp,pfilelist->section[pfilelist->head.h_index].f_size)<=1) /*temp>=size*/
		  {
		     EMPTY  pback;
			 pback.t_number.low=1;
			 pback.t_number.high=0;
			 pback.t_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
			 pback.t_type=PETAL_SINGLEEMPTY;
			 ResumeCluster(&pback);
			 pfilelist->section[pfilelist->head.h_index].f_size.low=0;
			 pfilelist->section[pfilelist->head.h_index].f_size.high=0;
			 pfilelist->section[pfilelist->head.h_index].f_startcluster.low=PETAL_INVALID;
			 pfilelist->section[pfilelist->head.h_index].f_startcluster.high=PETAL_INVALID;
			 pfilelist->section[pfilelist->head.h_index].f_type=PETAL_INVALID;			 
			 pfilelist->head.h_index++;
			 continue;
		  }
		  else
		  {
		     U4B   contentcontrol;FindFreeClusterControl(&contentcontrol);
			 PU1B  pcontent      =(PU1B)FSControlToAddress(contentcontrol);
			 LoadCluster(pfilelist->section[pfilelist->head.h_index].f_startcluster,contentcontrol);
			 PU1B  destination=pcontent+startoffset.low;
			 PU1B  source     =pcontent+endoffset.low;
			 PU1B  end        =pcontent+pfilelist->section[pfilelist->head.h_index].f_size.low;
			 for(;source<end;source++,destination++)
			 {
			    *destination=*source;
			 }
			 SaveDefaultControl(contentcontrol);			 
			 ReleaseControl(contentcontrol);
			 SubductULLONG(&temp,endoffset,startoffset);
			 SubductULLONG(&(pfilelist->section[pfilelist->head.h_index].f_size),pfilelist->section[pfilelist->head.h_index].f_size,temp);
			 pfilelist->head.h_index++;
			 continue;
		  }
		  
       }


	   /*----------------------------------------------------------------------------------------------------------------------*/
	   if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTINUOUS)
	   {
	      if(IamaZeroULLONGEntity(startoffset))
	      {
	         ULLONG q;
	         DivideULLONGU4B(&q,&temp,endoffset,sizeof(CLUSTER));/*In front ,we make sure that endoffset!=startoffset.*/
			 if(IamaZeroULLONGEntity(temp))
			 {
			    EMPTY pback;
				pback.t_number=q;
				pback.t_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
				if(q.low==1 && q.high==0) /*q==1*/
				{
				  pback.t_type=PETAL_SINGLEEMPTY;
				}
				else
			    {
			       pback.t_type=PETAL_CONTINUOUSEMPTY;
				}
				ResumeCluster(&pback);
				AddULLONG(&(pfilelist->section[pfilelist->head.h_index].f_startcluster),pfilelist->section[pfilelist->head.h_index].f_startcluster,q);
				SubductULLONG(&temp,endoffset,startoffset);
				SubductULLONG(&(pfilelist->section[pfilelist->head.h_index].f_size),pfilelist->section[pfilelist->head.h_index].f_size,temp);/*Change the size*/
				if(pfilelist->section[pfilelist->head.h_index].f_size.low==0 && pfilelist->section[pfilelist->head.h_index].f_size.high==0)
				{
				   pfilelist->section[pfilelist->head.h_index].f_type=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.high=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.low=PETAL_INVALID;
				}
				else
				{
                   if(CompareULLONGU4B(pfilelist->section[pfilelist->head.h_index].f_size,sizeof(CLUSTER))==1)
                   {
                      pfilelist->section[pfilelist->head.h_index].f_type=PETAL_CONTINUOUS;
                   }
				   else
				   {
				      pfilelist->section[pfilelist->head.h_index].f_type=PETAL_CONTENT;
				   }
				}
				pfilelist->head.h_index++;
				continue;
			 }		 
	      }


		  

          if(endoffset.high==pfilelist->section[pfilelist->head.h_index].f_size.high && endoffset.low==pfilelist->section[pfilelist->head.h_index].f_size.low)
          {
             ULLONG remain;
             DivideULLONGU4B(&temp,&remain,startoffset,sizeof(CLUSTER));
			 if(IamaZeroULLONGEntity(remain))
			 {
			    EMPTY p;
				ULLONG t;
				SubductULLONG(&t,endoffset,startoffset);
				SubductULLONG(&(pfilelist->section[pfilelist->head.h_index].f_size),pfilelist->section[pfilelist->head.h_index].f_size,t);/*Change the size*/
				ULLONG r;
				DivideULLONGU4B(&t,&r,t,sizeof(CLUSTER));
				p.t_number=t;
				AddULLONG(&(p.t_startcluster),pfilelist->section[pfilelist->head.h_index].f_startcluster,temp);
				if(CompareULLONGU4B(t,1)==1)
				{p.t_type=PETAL_CONTINUOUSEMPTY;}
				else
				{p.t_type=PETAL_SINGLEEMPTY;}
				ResumeCluster(&p);
				if(pfilelist->section[pfilelist->head.h_index].f_size.low==0 && pfilelist->section[pfilelist->head.h_index].f_size.high==0)
				{
				   pfilelist->section[pfilelist->head.h_index].f_type=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.high=PETAL_INVALID;
				   pfilelist->section[pfilelist->head.h_index].f_startcluster.low=PETAL_INVALID;
				}
				else
				{
                   if(CompareULLONGU4B(pfilelist->section[pfilelist->head.h_index].f_size,sizeof(CLUSTER))==1)
                   {
                      pfilelist->section[pfilelist->head.h_index].f_type=PETAL_CONTINUOUS;
                   }
				   else
				   {
				      pfilelist->section[pfilelist->head.h_index].f_type=PETAL_CONTENT;
				   }
				}
				pfilelist->head.h_index++;
				continue;
			 }
          }





          U4B extendcontrol=0;FindFreeClusterControl(&extendcontrol);
		  ULLONG nextlevel=pfilelist->head.h_level;
		  AddULLONGU4B(&nextlevel,nextlevel,1);
		  InitFileBuffer(extendcontrol,fscontrol[filelistcontrol].fromcluster,pfilelist->head.h_index,nextlevel);
		  ULLONG extendcluster;
		  ApplyForACluster(&extendcluster);
		  BindControlCluster(extendcontrol,extendcluster);
		  PPETALFILE pextend=(PPETALFILE)FSControlToAddress(extendcontrol);
		  
          /*----------------------------------0--------------------------------------------*/
          if(CompareULLONGU4B(startoffset,2*sizeof(CLUSTER))<=1)/*startoffset>=2*sizeof(CLUSTER)*/
          {
                pextend->section[0].f_type=PETAL_CONTINUOUS;
				ULLONG r;
				DivideULLONGU4B(&temp,&r,startoffset,sizeof(CLUSTER));
				MultiplyULLONGU4B(&(pextend->section[0].f_size),temp,sizeof(CLUSTER));
				pextend->section[0].f_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
          }
		  else
		  {
		     if(CompareULLONGU4B(startoffset,sizeof(CLUSTER))<=1)
		     {
		        pextend->section[0].f_type=PETAL_CONTENT;
				pextend->section[0].f_size.low=sizeof(CLUSTER);
				pextend->section[0].f_size.high=0;
				pextend->section[0].f_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
             }
			 else
			 {
			    pextend->section[0].f_size.high=0;pextend->section[0].f_size.low=0;
				pextend->section[0].f_startcluster.high=0;
				pextend->section[0].f_startcluster.low =0;
				pextend->section[0].f_type=PETAL_INVALID;
			 }
		  }

          /*----------------------------------1-------------------------------------------*/
		  
		  pextend->section[1].f_type=PETAL_CONTENT;
		  pextend->section[1].f_size.high=0;pextend->section[1].f_size.low=sizeof(CLUSTER);
		  pextend->head.h_firstindex=1;
		  pextend->head.h_index=1;
          if(pextend->section[0].f_type==PETAL_INVALID)
          {
             pextend->head.h_firstoffset=startoffset;
             pextend->section[1].f_startcluster=pfilelist->section[pfilelist->head.h_index].f_startcluster;
          }
		  else
		  {
		     ULLONG t,r;
			 DivideULLONGU4B(&t,&r,pextend->section[0].f_size,sizeof(CLUSTER));
			 AddULLONG(&t,pextend->section[0].f_startcluster,t);
			 pextend->section[1].f_startcluster=t;
			 SubductULLONG(&(pextend->head.h_firstoffset),startoffset,pextend->section[0].f_size);
		  }
		  /*---------------------------------2----------------------------------------------*/
          ULLONG t,r,m;
		  DivideULLONGU4B(&t,&r,endoffset,sizeof(CLUSTER));
		  DivideULLONGU4B(&temp,&r,startoffset,sizeof(CLUSTER));
		  SubductULLONG(&m,t,temp);
		  if(CompareULLONGU4B(m,2)==1)
		  {
		     SubductULLONGU4B(&m,m,1);
		     MultiplyULLONGU4B(&(pextend->section[2].f_size),m,sizeof(CLUSTER));
			 AddULLONGU4B(&(pextend->section[2].f_startcluster),pextend->section[1].f_startcluster,1);
			 pextend->section[2].f_type=PETAL_CONTINUOUS;
		  }
		  else
		  {
		     if(CompareULLONGU4B(m,2)==0)/*Only one */
		     {
		        pextend->section[2].f_size.high=0;pextend->section[2].f_size.low=sizeof(CLUSTER);
				AddULLONGU4B(&(pextend->section[2].f_startcluster),pextend->section[1].f_startcluster,1);
				pextend->section[2].f_type=PETAL_CONTENT;
		     }
			 else/*invalid*/
			 {
			    pextend->section[2].f_size.low=0;pextend->section[2].f_size.high=0;
				pextend->section[2].f_startcluster.high=PETAL_INVALID;
				pextend->section[2].f_startcluster.low=PETAL_INVALID;
				pextend->section[2].f_type=PETAL_INVALID;
			 }
		  }
        /*----------------------------------3--------------------------------------------------*/
		pextend->head.h_secondindex=3;
		DivideULLONGU4B(&t,&r,endoffset,sizeof(CLUSTER));
		DivideULLONGU4B(&temp,&r,startoffset,sizeof(CLUSTER));
	    SubductULLONG(&m,t,temp);
		if(IamaZeroULLONGEntity(m))
		{
		   pextend->section[3].f_type=PETAL_INVALID;
		   pextend->section[3].f_size.low=0;pextend->section[3].f_size.high=0;
		   pextend->section[3].f_startcluster.high=PETAL_INVALID;
		   pextend->section[3].f_startcluster.low =PETAL_INVALID;
		   pextend->head.h_secondindex=pextend->head.h_firstindex;
		   SubductULLONG(&(pextend->head.h_secondoffset),endoffset,pextend->section[0].f_size);
		}
		else
		{
		   pextend->section[3].f_type=PETAL_CONTENT;
		   pextend->section[3].f_size.high=0;pextend->section[3].f_size.low=sizeof(CLUSTER);
		   if(pextend->section[2].f_type==PETAL_INVALID)
		   {
		      AddULLONGU4B(&(pextend->section[3].f_startcluster),pextend->section[1].f_startcluster,1);
		   }
		   else
		   {
			  AddULLONG(&(pextend->section[3].f_startcluster),pfilelist->section[index].f_startcluster,t);
		   }
		   SubductULLONG(&(pextend->head.h_secondoffset),endoffset                     ,pextend->section[0].f_size);
		   SubductULLONG(&(pextend->head.h_secondoffset),(pextend->head.h_secondoffset),pextend->section[1].f_size);
		   SubductULLONG(&(pextend->head.h_secondoffset),(pextend->head.h_secondoffset),pextend->section[2].f_size);
		}
		/*----------------------------------4-------------------------------------------------------*/
		DivideULLONGU4B(&m,&r,pfilelist->section[index].f_size,sizeof(CLUSTER));
		SubductULLONGU4B(&t,m,1); 
		ULLONG n;
		AddULLONG(&n,pfilelist->section[index].f_startcluster,t);
		/*t:the cluster offset relative to the start cluster.*/
		/*n:the last    cluster.*/
		/*r:the content offset relative to the last cluster.*/
		if(pextend->section[3].f_type==PETAL_INVALID) /*if this take effects,then the section[2] is PETAL_INVALID*/
		{
		   if(CompareULLONG(pextend->section[1].f_startcluster,n)==0) 
		   {
		      pextend->section[4].f_type=PETAL_INVALID;
			  pextend->section[4].f_size.low=0;pextend->section[4].f_size.high=0;
			  pextend->section[4].f_startcluster.high=PETAL_INVALID;
			  pextend->section[4].f_startcluster.low =PETAL_INVALID;
		   }
		   else
		   {
		      SubductULLONG(&m,n,pextend->section[1].f_startcluster);
			  /*m:the number of cluster after the last cluster.*/
			  if(CompareULLONGU4B(m,2)<2)/*m>=2*/
			  {
			     pextend->section[4].f_type=PETAL_CONTINUOUS;
				 AddULLONGU4B(&(pextend->section[4].f_startcluster),(pextend->section[1].f_startcluster),1);
			     MultiplyULLONGU4B(&(pextend->section[4].f_size),m,sizeof(CLUSTER));
			  }
			  else
			  {
			     if(CompareULLONGU4B(m,1)==0) /*m==1*/
			     {
			       pextend->section[4].f_type=PETAL_CONTENT;
				   AddULLONGU4B(&(pextend->section[4].f_startcluster),(pextend->section[1].f_startcluster),1);
			       MultiplyULLONGU4B(&(pextend->section[4].f_size),m,sizeof(CLUSTER));
				 }
				 else
				 {
				   pextend->section[4].f_type=PETAL_INVALID;
				   pextend->section[4].f_startcluster.low=PETAL_INVALID;
				   pextend->section[4].f_startcluster.high=PETAL_INVALID;
				   pextend->section[4].f_size.low=0;
				   pextend->section[4].f_size.high=0;
				 }

			  }
		   }
		}
		else
		{
			if(CompareULLONG(pextend->section[3].f_startcluster,n)==0)
			{
			   pextend->section[4].f_type=PETAL_INVALID;
			   pextend->section[4].f_size.low=0;pextend->section[4].f_size.high=0;
			   pextend->section[4].f_startcluster.high=PETAL_INVALID;
			   pextend->section[4].f_startcluster.low =PETAL_INVALID;
			}
			else
			{
			   SubductULLONG(&m,n,pextend->section[3].f_startcluster);
			   /*m:the number of the remain cluster.*/
			   if(CompareULLONGU4B(m,2)<2)/*m>=2*/
			   {
				  pextend->section[4].f_type=PETAL_CONTINUOUS;
			   }
			   else
			   {
				  pextend->section[4].f_type=PETAL_CONTENT;
			   }
			   AddULLONGU4B(&(pextend->section[4].f_startcluster),(pextend->section[3].f_startcluster),1);
			   MultiplyULLONGU4B(&(pextend->section[4].f_size),m,sizeof(CLUSTER));
			} 
		}
        pfilelist->head.h_index++;
		SubductULLONG(&temp,endoffset,startoffset);
		SubductULLONG(&(pfilelist->section[index].f_size),(pfilelist->section[index].f_size),temp);
		pfilelist->section[index].f_startcluster=extendcluster;
		pfilelist->section[index].f_type=PETAL_EXTENDED;
		if(CompareULLONGU4B(pfilelist->section[index].f_size,0)==0)
		{
		    EMPTY pback;
			pback.t_number.high=0;pback.t_number.low=1;
			pback.t_startcluster=pfilelist->section[index].f_startcluster;
			pback.t_type=PETAL_SINGLEEMPTY;
			ResumeCluster(&pback);
			pfilelist->section[index].f_startcluster.low=PETAL_INVALID;
			pfilelist->section[index].f_startcluster.high=PETAL_INVALID;
			pfilelist->section[index].f_type=PETAL_INVALID;
		}
        SaveDefaultControl(filelistcontrol);
		U4B swap=filelistcontrol;
		filelistcontrol=extendcontrol;
		extendcontrol=swap;
		pfilelist=(PPETALFILE)FSControlToAddress(filelistcontrol);
		ReleaseControl(extendcontrol);
		level++;
		continue;
       }

/*-----------------------------------------------------------------------------------------------------------------*/
       if(pfilelist->section[index].f_type==PETAL_EXTENDED)
       {
          ULLONG size;
		  SubductULLONG(&size,endoffset,startoffset);
		  SubductULLONG(&(pfilelist->section[index].f_size),(pfilelist->section[index].f_size),size);
		  if(IamaZeroULLONGEntity(pfilelist->section[index].f_size))
		  {
		     pfilelist->section[index].f_type=PETAL_INVALID;
			 pfilelist->head.h_index++;
			 ULLONG next=pfilelist->section[index].f_startcluster;
			 pfilelist->section[index].f_startcluster.low=PETAL_INVALID;
			 pfilelist->section[index].f_startcluster.high=PETAL_INVALID;
			 SaveDefaultControl(filelistcontrol);	 
			 LoadCluster(next,filelistcontrol);
			 pfilelist->head.h_firstindex=0;
			 pfilelist->head.h_firstoffset.low=0;
			 pfilelist->head.h_index=0;
			 pfilelist->head.h_secondindex=125;
			 pfilelist->head.h_secondoffset=pfilelist->section[pfilelist->head.h_secondindex].f_size;
			 level++;
			 continue;
		  }

          pfilelist->head.h_index++;
          SaveDefaultControl(filelistcontrol);
          LoadCluster(pfilelist->section[index].f_startcluster,filelistcontrol);

	      number.low=0;number.high=0;	 
	      position=startoffset;	   
	      for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*//*Why not consider the situation that it's an empty file .We have prohibit this .*/
	      {
		      index++;
		      AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete beginning.*/
	      /*The offset*/
	      pfilelist->head.h_firstindex=index;
	      pfilelist->head.h_index=index;
	      SubductULLONG(&(pfilelist->head.h_firstoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_firstoffset),position,pfilelist->head.h_firstoffset);
	   
	      temp=endoffset;
	      for(;CompareULLONG(temp,number)<=1;)
	      {
		    index++;
		    AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete end.*/
	      pfilelist->head.h_secondindex=index;
	      SubductULLONG(&(pfilelist->head.h_secondoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_secondoffset),temp,pfilelist->head.h_secondoffset);
          level++;
	      continue;
       }
		  
		  
    }
	ReleaseControl(filelistcontrol);
	return 0;
}
PUBLIC S4B InsertOpenedFileContent(PFILEDESCRIPTOR pdescriptor)
{
  ULLONG      entrycluster;
  U4B         index;
  ULLONG      where    = pdescriptor->where;
  U4B         howmany  = pdescriptor->howmany.low;
  PU1B        pcontent =(PU1B)(pdescriptor->pointer);
  
  if(IamaZeroULLONGEntity(pdescriptor->location))
    return 1;
	
	
  entrycluster=pdescriptor->location;
  index       =pdescriptor->index;

  
  
  
  
  
  
  /*------------------------These to be released--------------------------------*/
  U4B entrycontrol=0;FindFreeClusterControl(&entrycontrol);
  U4B pfilecontrol=0;FindFreeClusterControl(&pfilecontrol);
  /*----------------------------------------------------------------------------*/




/*---------------------------------Something about the Directory----------------------------------------------------------------------------- */
    PPETALDIRECTORY plist=(PPETALDIRECTORY)FSControlToAddress(entrycontrol);
    LoadCluster(entrycluster,entrycontrol);/*bind the control and the specific cluster in the hd.*/
/*----------------------A file entryitem without nothing----------------------------------------*/
    if(plist->entry[index].e_startcluster.low==PETAL_INVALID && plist->entry[index].e_startcluster.high==PETAL_INVALID)
    {
       ULLONG newcluster;
       ApplyForACluster(&newcluster);
       U4B n=0;FindFreeClusterControl(&n);
	   ULLONG level;level.low=0;level.high=0;
	   InitFileBuffer(n,entrycluster,index,level);
       SaveCluster(n,newcluster);
       ReleaseControl(n);
       plist->entry[index].e_startcluster=newcluster;
       plist->entry[index].e_size.low=0;/*byte number*/
       plist->entry[index].e_size.high=0;/*byte number*/
    }
/*---------------------To protect the file----------------------------------*/
  if( CompareULLONG(where,plist->entry[index].e_size)==1) /*a file must less than 2^64Bytes*/
  {
     where=plist->entry[index].e_size; /*the entry cluster contain the size of the file*/
  }
/*---------------------To change the size .---------------------------------*/
    ULLONG sizetemp;sizetemp.high=0;sizetemp.low=howmany;
    AddULLONG(&(plist->entry[index].e_size),plist->entry[index].e_size,sizetemp);
    SaveDefaultControl(entrycontrol);
/*---------------------The File Directory Item Is END.-----------------------------------------------------------------------------------------*/





/*-------------------------Something about the File content list ------------------------------------------------------------------------------*/
    PPETALFILE pfilelist=(PPETALFILE)FSControlToAddress(pfilecontrol);
    LoadCluster(plist->entry[index].e_startcluster,pfilecontrol);
	
    ULLONG fileposition;
    fileposition.low=0;
    fileposition.high=0;
    U4B filelistindex=0;
    ULLONG offset;      /*In the find item the insert point offset*/
    offset.low=0;
    offset.high=0;
/*-------------------------------------------------------------------------------------------*/
    while(1)
    {

    /*--------------------------To find the insert point--------------------------------------------*/
            AddULLONG(&fileposition,fileposition,pfilelist->section[0].f_size);
            filelistindex=0;
            for(;CompareULLONG(where,fileposition)==1/*fileposition<where*/ ;)
            {
              	filelistindex++;
                AddULLONG(&fileposition,fileposition,pfilelist->section[filelistindex].f_size);
            }

            Assert(filelistindex<126);/*We know that "where" must less or equal the size of the file.*/

            if(pfilelist->section[filelistindex].f_type==PETAL_EXTENDED) 
            {
               SubductULLONG(&fileposition,fileposition,pfilelist->section[filelistindex].f_size);
               LoadCluster(pfilelist->section[filelistindex].f_startcluster,pfilecontrol);
			   continue;
            }
            else
            {
               SubductULLONG(&offset,fileposition,pfilelist->section[filelistindex].f_size);      
               SubductULLONG(&offset,where,offset);  /*the offset is for the begin of a  item*/
               break;
            }
    }
/*----------------------------------------First Period End-----------------------------------------------------*/
/*
offset           :it is a  variable contain the offset relative to the begining of one ITEM.
filelistindex    :in the pfilelist ,it is the index,where the content should be inserted.
plist            :it is the directory .
index      :in the plist ,it's the index of the directory item.
where              :the insert offset relative to the begining of the file.
entrycontrol      :it's a control block index.it contains the directory.
pfilecontrol        :it's a control block index.it contains the file content list.
pfilelist            :it conteins the file content list.
*/
/*-------------------------------------------------------------------------------------------------------------*/










  S4B         insertindex;   /*In the file content list ,it point to the one be inserted.*/
  ULLONG      insertcluster; /*The file content list cluster*/
  U4B         insertoffset;  /*The offset relative to the insert  cluster's beginning.*/



/*
---------------------------------------------------------------
Find the insert point ,the type can be :
    1:PETAL_CONTENT
    2:PETAL_CONTINUOUS
---------------------------------------------------------------
*/

  if(pfilelist->section[filelistindex].f_type==PETAL_CONTINUOUS)  /*If it's a continuous cluster....*/
  {
     ULLONG newcluster;
     U4B    newcontrol=0;FindFreeClusterControl(&newcontrol);
     ULLONG contcluster=pfilelist->section[filelistindex].f_startcluster;
     ULLONG contsize   =pfilelist->section[filelistindex].f_size;

     ApplyForACluster(&newcluster);
     pfilelist->section[filelistindex].f_type=PETAL_EXTENDED;   /*---------------CHANGED!!!!!!!!----------------*/
     pfilelist->section[filelistindex].f_startcluster=newcluster;
     AddULLONGU4B(&(pfilelist->section[filelistindex].f_size),contsize,howmany);/*-------------------Change the size.------------------*/
     SaveDefaultControl(pfilecontrol);/*--------------------------------SAVE IT--------------------------*/
	 ULLONG level;
	 AddULLONGU4B(&level,pfilelist->head.h_level,1);
     InitFileBuffer(newcontrol,fscontrol[pfilecontrol].fromcluster,filelistindex,level);
     BindControlCluster(newcontrol,newcluster);   /*--------------------Bind them-------------------*/

     PPETALFILE pnewlist=(PPETALFILE)FSControlToAddress(newcontrol);

     ULLONG j;
     j.low=sizeof(CLUSTER);
     j.high=0;
     if(CompareULLONG(j,offset)<=1)  /*the offset <= a cluster*//*the insert point is in the first cluster*/
     {
             pnewlist->section[0].f_type         =PETAL_CONTENT;
             pnewlist->section[0].f_size.high    =0;
             pnewlist->section[0].f_size.low     =sizeof(CLUSTER);
             pnewlist->section[0].f_startcluster =contcluster;

             insertindex=0;
             insertcluster=newcluster;
             insertoffset=offset.low;

             AddULLONGU4B(&contcluster,contcluster,1);

             SubductULLONGU4B(&contsize,contsize,sizeof(CLUSTER));           /*the second item need it.*/

             if(CompareULLONG(j,contsize)>=2)  /*contsize>sizeof(cluster)*/
             {
                pnewlist->section[1].f_type=PETAL_CONTINUOUS;
                pnewlist->section[1].f_size=contsize;
                pnewlist->section[1].f_startcluster=contcluster;
             }
             else
             {
                pnewlist->section[1].f_type=PETAL_CONTENT;
                pnewlist->section[1].f_size=contsize;
                pnewlist->section[1].f_startcluster=contcluster;
             }
     }
     else  /*the offset > a cluster*//*Two kinds*/
     {
           /*-------------------------------------------------------------------*/
           /*if the insert point is in the last cluster*/
            ULLONG k,m;
            m.low=sizeof(CLUSTER);
            m.high=0;
            SubductULLONG(&k,contsize,offset);

            if(CompareULLONG(k,m)>=2)  /*the insert point is in the last cluster*/
            {
               m.low=2*sizeof(CLUSTER);
               m.high=0;
               Assert(CompareULLONG(m,offset)!=0);/*if this take effects,the insert point should be not in the last cluster.*/
               if(CompareULLONG(m,offset)>=2)  /*PETAL_CONTINUOUS*/
               {
                  pnewlist->section[0].f_type=PETAL_CONTINUOUS;
               }
               else
               {
                  pnewlist->section[0].f_type=PETAL_CONTENT;
               }
               m.low=sizeof(CLUSTER);
               m.high=0;
               SubductULLONGU4B(&(pnewlist->section[0].f_size),contsize,sizeof(CLUSTER));
               pnewlist->section[0].f_startcluster=contcluster;
               pnewlist->section[1].f_type=PETAL_CONTENT;
               pnewlist->section[1].f_size=m;
               DivideULLONG(&m,&k,contsize,m);
               Assert(k.low==0);
               SubductULLONGU4B(&m,m,1);
               AddULLONG(&(pnewlist->section[1].f_startcluster),contcluster,m);
               insertindex=1;
               insertcluster=newcluster;
               SubductULLONG(&m,offset,pnewlist->section[0].f_size);
               insertoffset=m.low;
            }
            /*---------------------------------------------------------------------------------------*/
            else  /*the insert point in the middle of the continuous cluster*/
            {
                /*the first and third part can be PETAL_CONTINUOUS or PETAL_CONTENT*/
               /*The first part*/
               k=offset;
               m.low=1;
               m.high=0;
			   ULLONG remain;
               SubductULLONG(&k,k,m);
               DivideULLONGU4B(&k,&remain,k,sizeof(CLUSTER));
               Assert(k.low!=0);
               if(k.low<=1)
               {
                  pnewlist->section[0].f_type=PETAL_CONTENT;
                  pnewlist->section[0].f_size.low=sizeof(CLUSTER);
                  pnewlist->section[0].f_size.high=0;
                  pnewlist->section[0].f_startcluster=contcluster;
               }
               else
               {
                  
                  pnewlist->section[0].f_type=PETAL_CONTINUOUS;
				  //ULLONG temp;
				  MultiplyULLONGU4B(&(pnewlist->section[0].f_size),k,sizeof(CLUSTER));
                  pnewlist->section[0].f_startcluster=contcluster;
               }

               /*the third part*/
               SubductULLONG(&k,contsize,offset);
               DivideULLONGU4B(&k,&remain,k,sizeof(CLUSTER));
               Assert(k.low!=0);
               if(k.low<=1)
               {
                   pnewlist->section[2].f_type=PETAL_CONTENT;
                   pnewlist->section[2].f_size.low=sizeof(CLUSTER);
                   pnewlist->section[2].f_size.high=0;
                   DivideULLONGU4B(&k,&remain,contsize,sizeof(CLUSTER));
                   m.low=1;m.high=0;
                   AddULLONG(&k,contcluster,k);
                   SubductULLONG(&k,k,m);
                   pnewlist->section[2].f_startcluster=k;
               }
               else
               {
                   pnewlist->section[2].f_type=PETAL_CONTINUOUS;
                   MultiplyULLONGU4B(&(pnewlist->section[2].f_size),k,sizeof(CLUSTER));
				   ULLONG temp;
                   DivideULLONGU4B(&m,&temp,contsize,sizeof(CLUSTER));
                   AddULLONG(&m,contcluster,m);
                   SubductULLONG(&k,m,k);
                   pnewlist->section[2].f_startcluster=k;
               }
               /*the middle part*/
               pnewlist->section[1].f_type=PETAL_CONTENT;
               pnewlist->section[1].f_size.low=sizeof(CLUSTER);
               pnewlist->section[1].f_size.high=0;
               m.low=1;
               m.high=0;
               SubductULLONG(&(pnewlist->section[1].f_startcluster),pnewlist->section[2].f_startcluster,m);
               SubductULLONG(&m,offset,pnewlist->section[0].f_size);
               insertoffset=m.low;
               insertcluster=newcluster;
               insertindex=1;
            }

     }
     SaveCluster(newcontrol,newcluster);
     pfilelist=(PPETALFILE)FSControlToAddress(newcontrol);
     U4B  swapcontrol=newcontrol;
     newcontrol=pfilecontrol;
     pfilecontrol=swapcontrol;  /*We have bind  the newcontrol and newcluster.*/
     ReleaseControl(newcontrol);
  }
  else   /*A Common CONTENT*/
  {
       insertoffset=offset.low;
       insertcluster=entrycluster;
       insertindex=filelistindex;
  }

  /*If it's a empty file!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
  if(pfilelist->section[insertindex].f_startcluster.low==PETAL_INVALID && pfilelist->section[insertindex].f_startcluster.high==PETAL_INVALID)
  {
     pfilelist->section[insertindex].f_type=PETAL_CONTENT;
     pfilelist->section[insertindex].f_size.low=0;pfilelist->section[insertindex].f_size.high=0;
     ULLONG temp;
     ApplyForACluster(&temp);
     pfilelist->section[insertindex].f_startcluster=temp;
     SaveDefaultControl(pfilecontrol);
  }
/*The pfilecontrol has been bound to a specific cluster in the hd so far.*/
  Assert(insertoffset<=sizeof(CLUSTER));
  Assert(insertcluster.low!=PETAL_INVALID);
  Assert(pfilelist->section[insertindex].f_type==PETAL_CONTENT);
  Assert(pfilelist->section[insertindex].f_size.low>=insertoffset);
/*So far ,we just need to insert the content to a PETAL_CONTENT.*/
/*-----------------------The second period End---------------------------------------------------------------------------*/
/*
insertindex   :The index in pfilelist.It's a file content list index.It must point to a PETAL_FILEITEMPOINTER.
insertoffset   :Relative to the PETAL_FILEITEMPOINTER beginning.
insertcluster  :It shows the file content list cluster.
pfilelist         :it contain many file content list items.The insert point is in it.
pfilecontrol   :it's a control index of fscontrol,it is linked to the pfilelist.
*/








/*------------------------To insert the content.---------------------------------------------------------------------------*/

  U4B   textcontrol;FindFreeClusterControl(&textcontrol);
  LoadCluster(pfilelist->section[insertindex].f_startcluster,textcontrol);

  if(pfilelist->section[insertindex].f_size.low+howmany<=sizeof(CLUSTER))  /*The current cluster is enough .*/
  {
      PU1B movestart=(PU1B)FSControlToAddress(textcontrol);
      movestart+=insertoffset;    
      PU1B moveend=(PU1B)FSControlToAddress(textcontrol);
      moveend=moveend-1+pfilelist->section[insertindex].f_size.low;
      PU1B t=movestart;
      for(;movestart<=moveend;movestart++)
      {
         *(movestart+howmany)=*movestart;
      }
	  movestart=t;
      MemoryCopy((PCHAR)movestart,(PCHAR)pcontent,howmany);
      AddULLONGU4B(&(pfilelist->section[insertindex].f_size),(pfilelist->section[insertindex].f_size),howmany);/*Change the size.*/
      SaveDefaultControl(pfilecontrol);
      SaveDefaultControl(textcontrol);

      ReleaseControl(pfilecontrol);
      ReleaseControl(textcontrol);
      ReleaseControl(entrycontrol);
      return 0;
  }





/*---------------When the file is not enough for the content-------------*/
/*------------Apply for a cluster to place the squeezed content-------- */
  U4B   remaincontrol;FindFreeClusterControl(&remaincontrol);
  U4B   remainnumber;
  PU1B  remaincontent;

  PU1B  movestart=(PU1B)FSControlToAddress(textcontrol);
  movestart+=insertoffset;

  PU1B  movedestination=(PU1B)FSControlToAddress(remaincontrol);
  remaincontent=movedestination;
  remainnumber=(pfilelist->section[insertindex].f_size.low-insertoffset);

  MemoryCopy((PCHAR)movedestination,(PCHAR)movestart,remainnumber);

  U4B  toplacenumber=howmany;
  PCHAR toplacecontent=(PCHAR)pcontent;

  for(;movestart<(((PU1B)FSControlToAddress(textcontrol))+sizeof(CLUSTER)) && toplacenumber>0;)
  {
     *movestart=*toplacecontent;
     toplacecontent++;
     movestart++;
     toplacenumber--;
  }
  /*------The insert content is not enough to fill the cluster.The cluster is not full.-------*/
  if(movestart<(((PU1B)FSControlToAddress(textcontrol))+sizeof(CLUSTER))) 
  {
      for(;movestart<(((PU1B)FSControlToAddress(textcontrol))+sizeof(CLUSTER));movestart++)
      {
          *movestart=*remaincontent;
          remaincontent++;
          remainnumber--;
      }
      /*the remain content become the content to be placed */
      toplacecontent=(PCHAR)remaincontent;
      toplacenumber=remainnumber;
      remaincontent=PTR_INVALID;
      remainnumber=0;
  }
  pfilelist->section[insertindex].f_size.low=sizeof(CLUSTER);
  pfilelist->section[insertindex].f_size.high=0;
  SaveDefaultControl(textcontrol);
  SaveDefaultControl(pfilecontrol);
  /*the variable insertindex is the one has been used.*/
  while(1)
  {

        if(toplacenumber<=0 && remainnumber<=0)
            break;
      /*We try to collect PETAL_INVALID fileitem and move it to the next place near current one.*/
      /*-----In the fore place-----*/  
  
      S2B p=0,q=0;/*the first one is not used.*/
      while(p<insertindex)
      {
         for(;p<insertindex;p++)
         {
            if(pfilelist->section[p].f_type==PETAL_INVALID)
            {
               break;
            }
         }
         for(q=p;q<insertindex;q++)
         {
            pfilelist->section[q]=pfilelist->section[q+1];
            pfilelist->section[q+1].f_type=PETAL_INVALID;
         }
         if(p<insertindex)
         {insertindex--;}
      }
      /*The back*/
      p=125;
      while(p>(insertindex+1))
      {
         for(;p>(insertindex+1);p--)
         {
            if(pfilelist->section[p].f_type==PETAL_INVALID)
            {
               break;
            }
         }
         for(q=p;q>(insertindex+1);q--)
         {
            pfilelist->section[q]=pfilelist->section[q-1];
            pfilelist->section[q-1].f_type=PETAL_INVALID;
         }
      }
/*------------------------------------------------------------------------------------------------------------*/
         S4B  bytenumber=0;
INSERTFILE_NEXTINDEX:
        if(toplacenumber<=0 && remainnumber<=0)
            break;
      /*I have collect all the empty itempointer after the insertindex.*/
      insertindex++;   /*the next item*/
      if(insertindex>=126)      /*It means the previous one is the last one .*/
      {
          ULLONG   extendcluster;
          ApplyForACluster(&extendcluster);
          U4B extendcontrol=0;FindFreeClusterControl(&extendcontrol);
		  ULLONG level;
		  AddULLONGU4B(&level,pfilelist->head.h_level,1);
		  InitFileBuffer(extendcontrol,fscontrol[pfilecontrol].fromcluster,125,level);
          BindControlCluster(extendcontrol,extendcluster);
          PPETALFILE pextendlist=(PPETALFILE)FSControlToAddress(extendcontrol);
          pextendlist->section[0]=pfilelist->section[insertindex-1];
          SaveDefaultControl(extendcontrol);
          pfilelist->section[insertindex-1].f_type=PETAL_EXTENDED;
          pfilelist->section[insertindex-1].f_startcluster=extendcluster;
          AddULLONGU4B(&(pfilelist->section[insertindex-1].f_size),pfilelist->section[insertindex-1].f_size,(remainnumber+toplacenumber));
          SaveDefaultControl(pfilecontrol);
          U4B swapcontrol=pfilecontrol;
          pfilecontrol=extendcontrol;
          pfilelist=(PPETALFILE)FSControlToAddress(extendcontrol);
          extendcontrol=swapcontrol;  
          ReleaseControl(extendcontrol);
          insertindex=-1;
          continue;
      }
      if(pfilelist->section[insertindex].f_type==PETAL_INVALID)
      {
          ULLONG   contentcluster;
          ApplyForACluster(&contentcluster);
          U4B contentcontrol=0;FindFreeClusterControl(&contentcontrol);
          MemorySet((PVOID)FSControlToAddress(contentcontrol),sizeof(CLUSTER),0x0);
          BindControlCluster(contentcontrol,contentcluster);
          pfilelist->section[insertindex].f_type=PETAL_CONTENT;
          PU1B   filldestination=(PU1B)FSControlToAddress(contentcontrol);
         if((toplacenumber+remainnumber)>sizeof(CLUSTER))
         {
                    pfilelist->section[insertindex].f_size.high=0;pfilelist->section[insertindex].f_size.low=sizeof(CLUSTER);
         }
         else
         {
                    pfilelist->section[insertindex].f_size.high=0;pfilelist->section[insertindex].f_size.low=toplacenumber+remainnumber;
         }
		 U4B i=toplacenumber,j=remainnumber;
         for(bytenumber=0;bytenumber<i && bytenumber<sizeof(CLUSTER);bytenumber++)
         {
                 filldestination[bytenumber]=*((PU1B)toplacecontent);
                 toplacenumber--;
                 toplacecontent++;
         }
         for(;bytenumber<(i+j) && bytenumber<sizeof(CLUSTER);bytenumber++)
         {
                 filldestination[bytenumber]=*((PU1B)remaincontent);
                 remaincontent++;
                 remainnumber--;
         }
         SaveDefaultControl(pfilecontrol);
         SaveDefaultControl(contentcontrol);
         goto INSERTFILE_NEXTINDEX;
      }
      if(pfilelist->section[insertindex].f_type==PETAL_EXTENDED)
      {
          /*If enter the cluster,we will not return.*/
          AddULLONGU4B(&(pfilelist->section[insertindex].f_size),pfilelist->section[insertindex].f_size,(toplacenumber+remainnumber));
          SaveDefaultControl(pfilecontrol);
          LoadCluster(pfilelist->section[insertindex].f_startcluster,pfilecontrol);
          insertindex=-1;
          continue;
      }
	  /*Now the current one is valid.It can not provide empty space.*/
        ULLONG   extendcluster;
          ApplyForACluster(&extendcluster);
          U4B extendcontrol;FindFreeClusterControl(&extendcontrol);
		  ULLONG level;
		  AddULLONGU4B(&level,pfilelist->head.h_level,1);
		  InitFileBuffer(extendcontrol,fscontrol[pfilecontrol].fromcluster,insertindex,level);
          BindControlCluster(extendcontrol,extendcluster);
          PPETALFILE pextendlist=(PPETALFILE)FSControlToAddress(extendcontrol);
          pextendlist->section[1]=pfilelist->section[insertindex];
          SaveDefaultControl(extendcontrol);
          pfilelist->section[insertindex].f_type=PETAL_EXTENDED;
          pfilelist->section[insertindex].f_startcluster=extendcluster;
          AddULLONGU4B(&(pfilelist->section[insertindex].f_size),pfilelist->section[insertindex].f_size,(remainnumber+toplacenumber));
          SaveDefaultControl(pfilecontrol);
          U4B swapcontrol=pfilecontrol;
          pfilecontrol=extendcontrol;
          pfilelist=(PPETALFILE)FSControlToAddress(extendcontrol);
          extendcontrol=swapcontrol;  
          ReleaseControl(extendcontrol);
          insertindex=-1;

  }

 
  ReleaseControl(remaincontrol);
  ReleaseControl(textcontrol);
  ReleaseControl(entrycontrol);
  ReleaseControl(pfilecontrol);
  return 0;
}
PUBLIC S4B DeleteOpenedDirectory  (PFILEDESCRIPTOR pdescriptor)
{
  
   ULLONG directorycluster=pdescriptor->location;
   U4B    directoryindex  =pdescriptor->index;
  
   U4B directorycontrol=0;FindFreeClusterControl(&directorycontrol);
   PPETALDIRECTORY pdirectory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
   LoadCluster(directorycluster,directorycontrol);
   if(pdirectory->entry[directoryindex].e_type==PETAL_FILE)
   {
       FILEDESCRIPTOR d=*pdescriptor;
	   d.howmany.low=0xFFFFFFFF;d.howmany.high=0xFFFFFFFF;
	   d.where.low=0;d.where.high=0;
	   DeleteOpenedFileContent(&d);
   }
   if(!(IamaInvalidULLONGEntity(pdirectory->entry[directoryindex].e_startcluster))) /*the file not empty or the  directory not empty*/
        return 1;
   MemorySet((PVOID)(&(pdirectory->entry[directoryindex])),sizeof(DIRECTORYITEM),0);
   pdirectory->entry[directoryindex].e_type=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_startcluster.low=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_startcluster.high=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_size.low=0;
   pdirectory->entry[directoryindex].e_size.high=0;
   


   U4B upperdirectorycontrol=0;FindFreeClusterControl(&upperdirectorycontrol);
   PPETALDIRECTORY pupperdirectory=(PPETALDIRECTORY)FSControlToAddress(upperdirectorycontrol);
   LoadCluster(pdirectory->linker.l_upper,upperdirectorycontrol);
   SubductULLONGU4B(&(pupperdirectory->entry[pdirectory->linker.l_upperindex].e_size),pupperdirectory->entry[pdirectory->linker.l_upperindex].e_size,1); /*the item number decrease.*/
   
   directoryindex=0;
   for(;directoryindex<31;directoryindex++)
   {
       if(pdirectory->entry[directoryindex].e_type!=PETAL_INVALID)
	      break;
   }
   if(directoryindex<31)
   {
       SaveDefaultControl(upperdirectorycontrol);
	   SaveDefaultControl(directorycontrol);
	   ReleaseControl(upperdirectorycontrol);
	   ReleaseControl(directorycontrol);
	   return 0;
   }
   /*this directory cluster is empty now .Release it.*/
   
       EMPTY pback;
	   pback.t_type=PETAL_SINGLEEMPTY;
	   pback.t_startcluster=fscontrol[directorycontrol].fromcluster;
	   pback.t_number.low=1;pback.t_number.high=0;
	   ResumeCluster(&pback);
	   
       if(IamaZeroULLONGEntity(pdirectory->linker.l_previous)) /*this is the first cluster*/
	   {
		   pupperdirectory->entry[pdirectory->linker.l_upperindex].e_startcluster=pdirectory->linker.l_next;
	   }
       else
	   {
	       U4B previouscontrol;FindFreeClusterControl(&previouscontrol);
		   PPETALDIRECTORY pprevious=(PPETALDIRECTORY)FSControlToAddress(previouscontrol);
		   LoadCluster(pdirectory->linker.l_previous,previouscontrol);
		   pprevious->linker.l_next=pdirectory->linker.l_next;
		   SaveDefaultControl(previouscontrol);
		   ReleaseControl(previouscontrol);
	   }
   SaveDefaultControl(upperdirectorycontrol);
   /*because we have released the current directory cluster ,so we need not save it.*/
   ReleaseControl(upperdirectorycontrol);
   ReleaseControl(directorycontrol);
   return 0;
}
PUBLIC S4B DeleteOpenedFile       (PFILEDESCRIPTOR pdescriptor)
{
   
   ULLONG directorycluster=pdescriptor->location;
   U4B    directoryindex  =pdescriptor->index;
  
   U4B directorycontrol=0;FindFreeClusterControl(&directorycontrol);
   PPETALDIRECTORY pdirectory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
   LoadCluster(directorycluster,directorycontrol);
   if(pdirectory->entry[directoryindex].e_type==PETAL_FILE)
   {
       FILEDESCRIPTOR d=*pdescriptor;
	   d.howmany.low=0xFFFFFFFF;d.howmany.high=0xFFFFFFFF;
	   d.where.low=0;d.where.high=0;
	   DeleteOpenedFileContent(&d);
   }
   if(!(IamaInvalidULLONGEntity(pdirectory->entry[directoryindex].e_startcluster))) /*the file not empty or the  directory not empty*/
        return 1;
   MemorySet((PVOID)(&(pdirectory->entry[directoryindex])),sizeof(DIRECTORYITEM),0);
   pdirectory->entry[directoryindex].e_type=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_startcluster.low=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_startcluster.high=PETAL_INVALID;
   pdirectory->entry[directoryindex].e_size.low=0;
   pdirectory->entry[directoryindex].e_size.high=0;
   


   U4B upperdirectorycontrol=0;FindFreeClusterControl(&upperdirectorycontrol);
   PPETALDIRECTORY pupperdirectory=(PPETALDIRECTORY)FSControlToAddress(upperdirectorycontrol);
   LoadCluster(pdirectory->linker.l_upper,upperdirectorycontrol);
   SubductULLONGU4B(&(pupperdirectory->entry[pdirectory->linker.l_upperindex].e_size),pupperdirectory->entry[pdirectory->linker.l_upperindex].e_size,1); /*the item number decrease.*/
   
   directoryindex=0;
   for(;directoryindex<31;directoryindex++)
   {
       if(pdirectory->entry[directoryindex].e_type!=PETAL_INVALID)
	      break;
   }
   if(directoryindex<31)
   {
       SaveDefaultControl(upperdirectorycontrol);
	   SaveDefaultControl(directorycontrol);
	   ReleaseControl(upperdirectorycontrol);
	   ReleaseControl(directorycontrol);
	   return 0;
   }
   /*this directory cluster is empty now .Release it.*/
   
       EMPTY pback;
	   pback.t_type=PETAL_SINGLEEMPTY;
	   pback.t_startcluster=fscontrol[directorycontrol].fromcluster;
	   pback.t_number.low=1;pback.t_number.high=0;
	   ResumeCluster(&pback);
	   
       if(IamaZeroULLONGEntity(pdirectory->linker.l_previous)) /*this is the first cluster*/
	   {
		   pupperdirectory->entry[pdirectory->linker.l_upperindex].e_startcluster=pdirectory->linker.l_next;
	   }
       else
	   {
	       U4B previouscontrol;FindFreeClusterControl(&previouscontrol);
		   PPETALDIRECTORY pprevious=(PPETALDIRECTORY)FSControlToAddress(previouscontrol);
		   LoadCluster(pdirectory->linker.l_previous,previouscontrol);
		   pprevious->linker.l_next=pdirectory->linker.l_next;
		   SaveDefaultControl(previouscontrol);
		   ReleaseControl(previouscontrol);
	   }
   SaveDefaultControl(upperdirectorycontrol);
   /*because we have released the current directory cluster ,so we need not save it.*/
   ReleaseControl(upperdirectorycontrol);
   ReleaseControl(directorycontrol);
   return 0;
}
PUBLIC S4B ReadOpenedDirectory    (PFILEDESCRIPTOR pdescriptor)
{
   PDIRECTORYITEM pd=(PDIRECTORYITEM)(pdescriptor->pointer);
   MemorySet((PVOID)pd,sizeof(DIRECTORYITEM),0);
   ULLONG locationcluster=pdescriptor->location;
   U4B    locationindex=pdescriptor->index;
 
   U4B directorycontrol=0;
   FindFreeClusterControl(&directorycontrol);
   PPETALDIRECTORY pdirectory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
   LoadCluster(locationcluster,directorycontrol);
   *pd=pdirectory->entry[locationindex];
   ReleaseControl(directorycontrol);
   return 0;
}
PUBLIC S4B CloseOpenedFile        (PFILEDESCRIPTOR pdescriptor)
{
    return 0;
}
PUBLIC S4B CloseOpenedDirectory   (PFILEDESCRIPTOR pdescriptor)
{
    return 0;
}

PUBLIC S4B ReadOpenedFile         (PFILEDESCRIPTOR pdescriptor)
{
  /*------------------------------------------------------------------------------------*/
   /*Loacate the directory cluster.*/
    ULLONG cluster=pdescriptor->location;
    S4B    index=(S4B)pdescriptor->index;
    ULLONG length=pdescriptor->howmany;
    ULLONG position=pdescriptor->where;
    PU1B destination=(PU1B)pdescriptor->pointer;
    PULLONG pactuallength=&(pdescriptor->howmany);

    if(IamaZeroULLONGEntity(length))
	{
	   pactuallength->low=0;pactuallength->high=0;
	   return 0;
	}

	
    U4B        directorycontrol=0;
	FindFreeClusterControl(&directorycontrol);
    PPETALDIRECTORY directory=(PPETALDIRECTORY)FSControlToAddress(directorycontrol);
	LoadCluster(cluster,directorycontrol);

    /*Maybe ,this sentence is not necessary .However each step is independent.^_^*/
    if(directory->entry[index].e_type!=PETAL_FILE)

    {ReleaseControl(directorycontrol);return 1;}

	/*Maybe ,the directory has no cluster.*/
    if(directory->entry[index].e_startcluster.high==PETAL_INVALID && directory->entry[index].e_startcluster.low==PETAL_INVALID)
    {
      directory->entry[index].e_size.high=0;directory->entry[index].e_size.low=0;
	  SaveDefaultControl(directorycontrol);
      ReleaseControl(directorycontrol);
	  pactuallength->low=0;pactuallength->high=0;
	  return 0;
    }
	
	/*position>=size,if it's an empty file ,size=0,so the position must >=size,so return.read from the end of the file,it's so funny.*/ 
    if(CompareULLONG(position,directory->entry[index].e_size)<=1)
    {
        ReleaseControl(directorycontrol);
		pactuallength->low=0;pactuallength->high=0;
        return 0;
    }
	/*To protect the file.*/
    *pactuallength=length;
    ULLONG temp;
    SubductULLONG(&temp,directory->entry[index].e_size,position);
    if(CompareULLONG(temp,length)>=2)
    {
       length=temp;
	   *pactuallength=length;
    }

	/*-------------------------------------------------------------------------------------------*/
	
	U4B filelistcontrol=0;FindFreeClusterControl(&filelistcontrol);
	PPETALFILE pfilelist=(PPETALFILE)FSControlToAddress(filelistcontrol);
	LoadCluster(directory->entry[index].e_startcluster,filelistcontrol);/*We have ensure that the startcluster is valid.*/
    ReleaseControl(directorycontrol);
	
	ULLONG number;number.low=0;number.high=0;     
	for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*//*Why not consider the situation that it's an empty file .We have prohibit this .*/
	{
	    index++;
        AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index<0)  /*Maybe it's not used.*/
	{
	    ReleaseControl(filelistcontrol);
		return 1;
	}
	/*Ok,we now get the index,which contain the read beginning.*/
	/*The offset*/
	U4B startindex=index;
	ULLONG startoffset;
	SubductULLONG(&startoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&startoffset,position,startoffset);
	
	AddULLONG(&temp,position,length);
    for(;CompareULLONG(temp,number)==1;)
    {
      index++;
	  AddULLONG(&number,number,pfilelist->section[index].f_size);
    }
	if(index>=126)
	{
	   ReleaseControl(filelistcontrol);
	   pactuallength->low=0;
	   pactuallength->high=0;
	   return 1;/*there must be something wrong with this file.*/
	}
    /*Ok,we now get the index,which contain the read end.*/
	U4B endindex=index;
	ULLONG endoffset;
	SubductULLONG(&endoffset,number,pfilelist->section[index].f_size);
	SubductULLONG(&endoffset,temp,endoffset);
	Assert(endindex>=startindex) /*to protect the fs*/
	/*--------------------------------------------------------------------------------*/
	/*
	     We sum up the variables now.
	     
	     startindex:      the index that the delete beginning in
	     startoffset:      the delete point relative to the clusters the index presents
	     endindex:        the index the end delete point
	     endoffset:       the offset relative to the end index
	     temp:             temporary ULLONG variable
	     number:         tempory ULLONG variable
	     pfilelist:          contain the file content pointer.
	*/
	
/*---------------------------------------------------------------------------------------------------------------------------------------*/

	
    U4B level=1;
	pfilelist->head.h_index=startindex;
    pfilelist->head.h_firstindex=startindex;
	pfilelist->head.h_firstoffset=startoffset;
	pfilelist->head.h_secondindex=endindex;
	pfilelist->head.h_secondoffset=endoffset;
    SaveDefaultControl(filelistcontrol);
	
    /*
            To increase the depth ,we should set the header,when decrease the depth ,we should fetch the header.
            The header is about the current level,it have a item "upper",it point to the previous level.
	*/
	
	while(1)
	{		
	   if(level==0)
	   {
	      ReleaseControl(filelistcontrol);
	      return 0;
	   }
	   if(pfilelist->head.h_index>pfilelist->head.h_secondindex)
	   {
	     
	         LoadCluster(pfilelist->head.h_upper,filelistcontrol);
		     level--;
		     continue;
	   }
	   
	   index=pfilelist->head.h_index;	 
	   
	   if(pfilelist->head.h_firstindex==pfilelist->head.h_index)
	   {  
		   startoffset=pfilelist->head.h_firstoffset;
	   }
	   else
	   {
	       startoffset.low=0;
		   startoffset.high=0;
	   }
	   if(pfilelist->head.h_index==pfilelist->head.h_secondindex)
	   {
	       endoffset=pfilelist->head.h_secondoffset;
		   if(CompareULLONG(endoffset,pfilelist->section[pfilelist->head.h_index].f_size)==1)/*Protect the file*/
		   {
		      endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
		   }
	   }
	   else
	   {
	     endoffset=pfilelist->section[pfilelist->head.h_index].f_size;
	   }



       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_INVALID
	      || IamaZeroULLONGEntity(pfilelist->section[pfilelist->head.h_index].f_size))
       {
          pfilelist->head.h_index++;
		  continue;
       }

	   if(startoffset.low==endoffset.low && startoffset.high==endoffset.high)
	   {
	      pfilelist->head.h_index++;
		  continue;
	   }
	   //-----------2012.4.3 in the library.Oh,My God ,I need a computer.--------------------------------------------------------------
       if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTENT)
       {
	      U4B contentcontrol;
		  FindFreeClusterControl(&contentcontrol);
		  PU1B pcontent=(PU1B)FSControlToAddress(contentcontrol);
		  LoadCluster(pfilelist->section[pfilelist->head.h_index].f_startcluster,contentcontrol);
          U4B number=endoffset.low-startoffset.low;
		  
          MemoryCopy((PCHAR)destination,(PCHAR)((PCHAR)pcontent+startoffset.low),number);
		  destination+=(number);
		  ReleaseControl(contentcontrol);
	      pfilelist->head.h_index++;
		  continue;	  
       }


	   /*-------------------------------2012.4.3.9.26-----------------------------------------------------------------------*/
	   if(pfilelist->section[pfilelist->head.h_index].f_type==PETAL_CONTINUOUS)
       {
	       ULLONG firstcluster,lastcluster,firstoffset,lastoffset;
		   DivideULLONGU4B(&firstcluster,&firstoffset,startoffset,sizeof(CLUSTER));
		   AddULLONG(&firstcluster,firstcluster,pfilelist->section[pfilelist->head.h_index].f_startcluster);
		   DivideULLONGU4B(&lastcluster, &lastoffset, endoffset,  sizeof(CLUSTER));
		   AddULLONG(&lastcluster,lastcluster,pfilelist->section[pfilelist->head.h_index].f_startcluster);
		   /*

		       firstcluster:the first cluster we should read
			   firstoffset :the offset relative to the firstcluster.
			   lastcluster :......

			   lastoffset  :......  
		   */
		   ULLONG i=firstcluster;
		   U4B readstart;
           U4B readend;	
		   U4B contentcontrol;
		   FindFreeClusterControl(&contentcontrol);
		   PU1B pcontent=(PU1B)FSControlToAddress(contentcontrol);

		   for(;CompareULLONG(lastcluster,i)<2;AddULLONGU4B(&i,i,1))

		   {
		       if(i.low==firstcluster.low && i.high==firstcluster.high)
			   {readstart=firstoffset.low;}
			   else
			   {readstart=0;}
			   
			   if(i.low==lastcluster.low && i.high==lastcluster.high)
			   {readend=lastoffset.low;}
			   else
			   {readend=sizeof(CLUSTER);}
			   
			   LoadCluster(i,contentcontrol);
			   
			   PU1B readpointer=pcontent+readstart;
			   for(;readpointer<(pcontent+readend);readpointer++)
			   {
			       *destination=*readpointer;
				   destination++;
			   }
			   
		   }
		   ReleaseControl(contentcontrol);
	       pfilelist->head.h_index++;
		   continue;
	   }
/*-----------------------------------------------------------------------------------------------------------------*/
       if(pfilelist->section[index].f_type==PETAL_EXTENDED)
       {
          

          pfilelist->head.h_index++;
          SaveDefaultControl(filelistcontrol);
          LoadCluster(pfilelist->section[index].f_startcluster,filelistcontrol);


       
	      number.low=0;number.high=0;	 
	      position=startoffset;
	   
	      for(index=-1;CompareULLONG(position,number)<=1;)/*position>=number*/
	      {
		      index++;
		      AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete beginning.*/
	      /*The offset*/
	      pfilelist->head.h_firstindex=index;
	      pfilelist->head.h_index=index;
	      SubductULLONG(&(pfilelist->head.h_firstoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_firstoffset),position,pfilelist->head.h_firstoffset);
	   
	      temp=endoffset;
	      for(;CompareULLONG(temp,number)<=1;)
	      {
		    index++;
		    AddULLONG(&number,number,pfilelist->section[index].f_size);
	      }
	      /*Ok,we now get the index,which contain the delete end.*/
	      pfilelist->head.h_secondindex=index;
	      SubductULLONG(&(pfilelist->head.h_secondoffset),number,pfilelist->section[index].f_size);
	      SubductULLONG(&(pfilelist->head.h_secondoffset),temp,pfilelist->head.h_secondoffset);
          level++;
	      continue;
       }
		  
	   pfilelist->head.h_index++;  /*this sentence is important .Because there may be some wrong with the file system.*/
    }
	ReleaseControl(filelistcontrol);
   
   return 0;
}

PUBLIC S4B FSOpenFile(PFILEDESCRIPTOR pdescriptor)
{
   MESSAGE message;
   message.destination=FSSERVER;
   message.type=FSSERVER_OPENFILE;
   message.value0=(U4B)(pdescriptor);
   SendMessage(&message);
   SIGNAL signal;
   signal.dt=0;
   signal.signal=FSSERVER_OPENFILE;
   signal.sourcepid=FSSERVER;
   WaitSignal(&signal);
   
   return signal.returnvalue;
}

PUBLIC S4B FSReadDirectory(PFILEDESCRIPTOR pdescriptor)
{
    
	MESSAGE message;
	message.destination=FSSERVER;
	message.type=FSSERVER_READDIRECTORY;
	message.value0=(U4B)(pdescriptor);
	SendMessage(&message);
	SIGNAL signal;
	signal.dt=0;
	signal.signal=FSSERVER_READDIRECTORY;
	signal.sourcepid=FSSERVER;
	WaitSignal(&signal);
	
	return signal.returnvalue;
}

PUBLIC S4B FSReadFile(PFILEDESCRIPTOR pdescriptor)
{
    
	MESSAGE message;
	message.destination=FSSERVER;
	message.type=FSSERVER_READFILE;
	message.value0=(U4B)(pdescriptor);
	SendMessage(&message);
	SIGNAL signal;
	signal.dt=0;
	signal.signal=FSSERVER_READFILE;
	signal.sourcepid=FSSERVER;
	WaitSignal(&signal);
	
	return signal.returnvalue;
}
